]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_type_ir/src/sty.rs
Auto merge of #98324 - conradludgate:write-vectored-vec, r=Mark-Simulacrum
[rust.git] / compiler / rustc_type_ir / src / sty.rs
1 #![allow(rustc::usage_of_ty_tykind)]
2
3 use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
4 use std::{fmt, hash};
5
6 use crate::DebruijnIndex;
7 use crate::FloatTy;
8 use crate::IntTy;
9 use crate::Interner;
10 use crate::TyDecoder;
11 use crate::TyEncoder;
12 use crate::UintTy;
13 use crate::UniverseIndex;
14
15 use self::RegionKind::*;
16 use self::TyKind::*;
17
18 use rustc_data_structures::stable_hasher::HashStable;
19 use rustc_serialize::{Decodable, Decoder, Encodable};
20
21 /// Defines the kinds of types used by the type system.
22 ///
23 /// Types written by the user start out as `hir::TyKind` and get
24 /// converted to this representation using `AstConv::ast_ty_to_ty`.
25 #[rustc_diagnostic_item = "IrTyKind"]
26 pub enum TyKind<I: Interner> {
27     /// The primitive boolean type. Written as `bool`.
28     Bool,
29
30     /// The primitive character type; holds a Unicode scalar value
31     /// (a non-surrogate code point). Written as `char`.
32     Char,
33
34     /// A primitive signed integer type. For example, `i32`.
35     Int(IntTy),
36
37     /// A primitive unsigned integer type. For example, `u32`.
38     Uint(UintTy),
39
40     /// A primitive floating-point type. For example, `f64`.
41     Float(FloatTy),
42
43     /// Algebraic data types (ADT). For example: structures, enumerations and unions.
44     ///
45     /// For example, the type `List<i32>` would be represented using the `AdtDef`
46     /// for `struct List<T>` and the substs `[i32]`.
47     ///
48     /// Note that generic parameters in fields only get lazily substituted
49     /// by using something like `adt_def.all_fields().map(|field| field.ty(tcx, substs))`.
50     Adt(I::AdtDef, I::SubstsRef),
51
52     /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
53     Foreign(I::DefId),
54
55     /// The pointee of a string slice. Written as `str`.
56     Str,
57
58     /// An array with the given length. Written as `[T; N]`.
59     Array(I::Ty, I::Const),
60
61     /// The pointee of an array slice. Written as `[T]`.
62     Slice(I::Ty),
63
64     /// A raw pointer. Written as `*mut T` or `*const T`
65     RawPtr(I::TypeAndMut),
66
67     /// A reference; a pointer with an associated lifetime. Written as
68     /// `&'a mut T` or `&'a T`.
69     Ref(I::Region, I::Ty, I::Mutability),
70
71     /// The anonymous type of a function declaration/definition. Each
72     /// function has a unique type.
73     ///
74     /// For the function `fn foo() -> i32 { 3 }` this type would be
75     /// shown to the user as `fn() -> i32 {foo}`.
76     ///
77     /// For example the type of `bar` here:
78     /// ```rust
79     /// fn foo() -> i32 { 1 }
80     /// let bar = foo; // bar: fn() -> i32 {foo}
81     /// ```
82     FnDef(I::DefId, I::SubstsRef),
83
84     /// A pointer to a function. Written as `fn() -> i32`.
85     ///
86     /// Note that both functions and closures start out as either
87     /// [FnDef] or [Closure] which can be then be coerced to this variant.
88     ///
89     /// For example the type of `bar` here:
90     ///
91     /// ```rust
92     /// fn foo() -> i32 { 1 }
93     /// let bar: fn() -> i32 = foo;
94     /// ```
95     FnPtr(I::PolyFnSig),
96
97     /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
98     Dynamic(I::ListBinderExistentialPredicate, I::Region),
99
100     /// The anonymous type of a closure. Used to represent the type of `|a| a`.
101     ///
102     /// Closure substs contain both the - potentially substituted - generic parameters
103     /// of its parent and some synthetic parameters. See the documentation for
104     /// `ClosureSubsts` for more details.
105     Closure(I::DefId, I::SubstsRef),
106
107     /// The anonymous type of a generator. Used to represent the type of
108     /// `|a| yield a`.
109     ///
110     /// For more info about generator substs, visit the documentation for
111     /// `GeneratorSubsts`.
112     Generator(I::DefId, I::SubstsRef, I::Movability),
113
114     /// A type representing the types stored inside a generator.
115     /// This should only appear as part of the `GeneratorSubsts`.
116     ///
117     /// Note that the captured variables for generators are stored separately
118     /// using a tuple in the same way as for closures.
119     ///
120     /// Unlike upvars, the witness can reference lifetimes from
121     /// inside of the generator itself. To deal with them in
122     /// the type of the generator, we convert them to higher ranked
123     /// lifetimes bound by the witness itself.
124     ///
125     /// Looking at the following example, the witness for this generator
126     /// may end up as something like `for<'a> [Vec<i32>, &'a Vec<i32>]`:
127     ///
128     /// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?)
129     /// #![feature(generators)]
130     /// |a| {
131     ///     let x = &vec![3];
132     ///     yield a;
133     ///     yield x[0];
134     /// }
135     /// # ;
136     /// ```
137     GeneratorWitness(I::BinderListTy),
138
139     /// The never type `!`.
140     Never,
141
142     /// A tuple type. For example, `(i32, bool)`.
143     Tuple(I::ListTy),
144
145     /// The projection of an associated type. For example,
146     /// `<T as Trait<..>>::N`.
147     Projection(I::ProjectionTy),
148
149     /// Opaque (`impl Trait`) type found in a return type.
150     ///
151     /// The `DefId` comes either from
152     /// * the `impl Trait` ast::Ty node,
153     /// * or the `type Foo = impl Trait` declaration
154     ///
155     /// For RPIT the substitutions are for the generics of the function,
156     /// while for TAIT it is used for the generic parameters of the alias.
157     ///
158     /// During codegen, `tcx.type_of(def_id)` can be used to get the underlying type.
159     Opaque(I::DefId, I::SubstsRef),
160
161     /// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
162     Param(I::ParamTy),
163
164     /// Bound type variable, used to represent the `'a` in `for<'a> fn(&'a ())`.
165     ///
166     /// For canonical queries, we replace inference variables with bound variables,
167     /// so e.g. when checking whether `&'_ (): Trait<_>` holds, we canonicalize that to
168     /// `for<'a, T> &'a (): Trait<T>` and then convert the introduced bound variables
169     /// back to inference variables in a new inference context when inside of the query.
170     ///
171     /// See the `rustc-dev-guide` for more details about
172     /// [higher-ranked trait bounds][1] and [canonical queries][2].
173     ///
174     /// [1]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
175     /// [2]: https://rustc-dev-guide.rust-lang.org/traits/canonical-queries.html
176     Bound(DebruijnIndex, I::BoundTy),
177
178     /// A placeholder type, used during higher ranked subtyping to instantiate
179     /// bound variables.
180     Placeholder(I::PlaceholderType),
181
182     /// A type variable used during type checking.
183     ///
184     /// Similar to placeholders, inference variables also live in a universe to
185     /// correctly deal with higher ranked types. Though unlike placeholders,
186     /// that universe is stored in the `InferCtxt` instead of directly
187     /// inside of the type.
188     Infer(I::InferTy),
189
190     /// A placeholder for a type which could not be computed; this is
191     /// propagated to avoid useless error messages.
192     Error(I::DelaySpanBugEmitted),
193 }
194
195 impl<I: Interner> TyKind<I> {
196     #[inline]
197     pub fn is_primitive(&self) -> bool {
198         matches!(self, Bool | Char | Int(_) | Uint(_) | Float(_))
199     }
200 }
201
202 // This is manually implemented for `TyKind` because `std::mem::discriminant`
203 // returns an opaque value that is `PartialEq` but not `PartialOrd`
204 #[inline]
205 const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
206     match value {
207         Bool => 0,
208         Char => 1,
209         Int(_) => 2,
210         Uint(_) => 3,
211         Float(_) => 4,
212         Adt(_, _) => 5,
213         Foreign(_) => 6,
214         Str => 7,
215         Array(_, _) => 8,
216         Slice(_) => 9,
217         RawPtr(_) => 10,
218         Ref(_, _, _) => 11,
219         FnDef(_, _) => 12,
220         FnPtr(_) => 13,
221         Dynamic(_, _) => 14,
222         Closure(_, _) => 15,
223         Generator(_, _, _) => 16,
224         GeneratorWitness(_) => 17,
225         Never => 18,
226         Tuple(_) => 19,
227         Projection(_) => 20,
228         Opaque(_, _) => 21,
229         Param(_) => 22,
230         Bound(_, _) => 23,
231         Placeholder(_) => 24,
232         Infer(_) => 25,
233         Error(_) => 26,
234     }
235 }
236
237 // This is manually implemented because a derive would require `I: Clone`
238 impl<I: Interner> Clone for TyKind<I> {
239     fn clone(&self) -> Self {
240         match self {
241             Bool => Bool,
242             Char => Char,
243             Int(i) => Int(i.clone()),
244             Uint(u) => Uint(u.clone()),
245             Float(f) => Float(f.clone()),
246             Adt(d, s) => Adt(d.clone(), s.clone()),
247             Foreign(d) => Foreign(d.clone()),
248             Str => Str,
249             Array(t, c) => Array(t.clone(), c.clone()),
250             Slice(t) => Slice(t.clone()),
251             RawPtr(t) => RawPtr(t.clone()),
252             Ref(r, t, m) => Ref(r.clone(), t.clone(), m.clone()),
253             FnDef(d, s) => FnDef(d.clone(), s.clone()),
254             FnPtr(s) => FnPtr(s.clone()),
255             Dynamic(p, r) => Dynamic(p.clone(), r.clone()),
256             Closure(d, s) => Closure(d.clone(), s.clone()),
257             Generator(d, s, m) => Generator(d.clone(), s.clone(), m.clone()),
258             GeneratorWitness(g) => GeneratorWitness(g.clone()),
259             Never => Never,
260             Tuple(t) => Tuple(t.clone()),
261             Projection(p) => Projection(p.clone()),
262             Opaque(d, s) => Opaque(d.clone(), s.clone()),
263             Param(p) => Param(p.clone()),
264             Bound(d, b) => Bound(d.clone(), b.clone()),
265             Placeholder(p) => Placeholder(p.clone()),
266             Infer(t) => Infer(t.clone()),
267             Error(e) => Error(e.clone()),
268         }
269     }
270 }
271
272 // This is manually implemented because a derive would require `I: PartialEq`
273 impl<I: Interner> PartialEq for TyKind<I> {
274     #[inline]
275     fn eq(&self, other: &TyKind<I>) -> bool {
276         let __self_vi = tykind_discriminant(self);
277         let __arg_1_vi = tykind_discriminant(other);
278         if __self_vi == __arg_1_vi {
279             match (&*self, &*other) {
280                 (&Int(ref __self_0), &Int(ref __arg_1_0)) => __self_0 == __arg_1_0,
281                 (&Uint(ref __self_0), &Uint(ref __arg_1_0)) => __self_0 == __arg_1_0,
282                 (&Float(ref __self_0), &Float(ref __arg_1_0)) => __self_0 == __arg_1_0,
283                 (&Adt(ref __self_0, ref __self_1), &Adt(ref __arg_1_0, ref __arg_1_1)) => {
284                     __self_0 == __arg_1_0 && __self_1 == __arg_1_1
285                 }
286                 (&Foreign(ref __self_0), &Foreign(ref __arg_1_0)) => __self_0 == __arg_1_0,
287                 (&Array(ref __self_0, ref __self_1), &Array(ref __arg_1_0, ref __arg_1_1)) => {
288                     __self_0 == __arg_1_0 && __self_1 == __arg_1_1
289                 }
290                 (&Slice(ref __self_0), &Slice(ref __arg_1_0)) => __self_0 == __arg_1_0,
291                 (&RawPtr(ref __self_0), &RawPtr(ref __arg_1_0)) => __self_0 == __arg_1_0,
292                 (
293                     &Ref(ref __self_0, ref __self_1, ref __self_2),
294                     &Ref(ref __arg_1_0, ref __arg_1_1, ref __arg_1_2),
295                 ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1 && __self_2 == __arg_1_2,
296                 (&FnDef(ref __self_0, ref __self_1), &FnDef(ref __arg_1_0, ref __arg_1_1)) => {
297                     __self_0 == __arg_1_0 && __self_1 == __arg_1_1
298                 }
299                 (&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => __self_0 == __arg_1_0,
300                 (&Dynamic(ref __self_0, ref __self_1), &Dynamic(ref __arg_1_0, ref __arg_1_1)) => {
301                     __self_0 == __arg_1_0 && __self_1 == __arg_1_1
302                 }
303                 (&Closure(ref __self_0, ref __self_1), &Closure(ref __arg_1_0, ref __arg_1_1)) => {
304                     __self_0 == __arg_1_0 && __self_1 == __arg_1_1
305                 }
306                 (
307                     &Generator(ref __self_0, ref __self_1, ref __self_2),
308                     &Generator(ref __arg_1_0, ref __arg_1_1, ref __arg_1_2),
309                 ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1 && __self_2 == __arg_1_2,
310                 (&GeneratorWitness(ref __self_0), &GeneratorWitness(ref __arg_1_0)) => {
311                     __self_0 == __arg_1_0
312                 }
313                 (&Tuple(ref __self_0), &Tuple(ref __arg_1_0)) => __self_0 == __arg_1_0,
314                 (&Projection(ref __self_0), &Projection(ref __arg_1_0)) => __self_0 == __arg_1_0,
315                 (&Opaque(ref __self_0, ref __self_1), &Opaque(ref __arg_1_0, ref __arg_1_1)) => {
316                     __self_0 == __arg_1_0 && __self_1 == __arg_1_1
317                 }
318                 (&Param(ref __self_0), &Param(ref __arg_1_0)) => __self_0 == __arg_1_0,
319                 (&Bound(ref __self_0, ref __self_1), &Bound(ref __arg_1_0, ref __arg_1_1)) => {
320                     __self_0 == __arg_1_0 && __self_1 == __arg_1_1
321                 }
322                 (&Placeholder(ref __self_0), &Placeholder(ref __arg_1_0)) => __self_0 == __arg_1_0,
323                 (&Infer(ref __self_0), &Infer(ref __arg_1_0)) => __self_0 == __arg_1_0,
324                 (&Error(ref __self_0), &Error(ref __arg_1_0)) => __self_0 == __arg_1_0,
325                 _ => true,
326             }
327         } else {
328             false
329         }
330     }
331 }
332
333 // This is manually implemented because a derive would require `I: Eq`
334 impl<I: Interner> Eq for TyKind<I> {}
335
336 // This is manually implemented because a derive would require `I: PartialOrd`
337 impl<I: Interner> PartialOrd for TyKind<I> {
338     #[inline]
339     fn partial_cmp(&self, other: &TyKind<I>) -> Option<Ordering> {
340         Some(Ord::cmp(self, other))
341     }
342 }
343
344 // This is manually implemented because a derive would require `I: Ord`
345 impl<I: Interner> Ord for TyKind<I> {
346     #[inline]
347     fn cmp(&self, other: &TyKind<I>) -> Ordering {
348         let __self_vi = tykind_discriminant(self);
349         let __arg_1_vi = tykind_discriminant(other);
350         if __self_vi == __arg_1_vi {
351             match (&*self, &*other) {
352                 (&Int(ref __self_0), &Int(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
353                 (&Uint(ref __self_0), &Uint(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
354                 (&Float(ref __self_0), &Float(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
355                 (&Adt(ref __self_0, ref __self_1), &Adt(ref __arg_1_0, ref __arg_1_1)) => {
356                     match Ord::cmp(__self_0, __arg_1_0) {
357                         Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
358                         cmp => cmp,
359                     }
360                 }
361                 (&Foreign(ref __self_0), &Foreign(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
362                 (&Array(ref __self_0, ref __self_1), &Array(ref __arg_1_0, ref __arg_1_1)) => {
363                     match Ord::cmp(__self_0, __arg_1_0) {
364                         Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
365                         cmp => cmp,
366                     }
367                 }
368                 (&Slice(ref __self_0), &Slice(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
369                 (&RawPtr(ref __self_0), &RawPtr(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
370                 (
371                     &Ref(ref __self_0, ref __self_1, ref __self_2),
372                     &Ref(ref __arg_1_0, ref __arg_1_1, ref __arg_1_2),
373                 ) => match Ord::cmp(__self_0, __arg_1_0) {
374                     Ordering::Equal => match Ord::cmp(__self_1, __arg_1_1) {
375                         Ordering::Equal => Ord::cmp(__self_2, __arg_1_2),
376                         cmp => cmp,
377                     },
378                     cmp => cmp,
379                 },
380                 (&FnDef(ref __self_0, ref __self_1), &FnDef(ref __arg_1_0, ref __arg_1_1)) => {
381                     match Ord::cmp(__self_0, __arg_1_0) {
382                         Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
383                         cmp => cmp,
384                     }
385                 }
386                 (&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
387                 (&Dynamic(ref __self_0, ref __self_1), &Dynamic(ref __arg_1_0, ref __arg_1_1)) => {
388                     match Ord::cmp(__self_0, __arg_1_0) {
389                         Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
390                         cmp => cmp,
391                     }
392                 }
393                 (&Closure(ref __self_0, ref __self_1), &Closure(ref __arg_1_0, ref __arg_1_1)) => {
394                     match Ord::cmp(__self_0, __arg_1_0) {
395                         Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
396                         cmp => cmp,
397                     }
398                 }
399                 (
400                     &Generator(ref __self_0, ref __self_1, ref __self_2),
401                     &Generator(ref __arg_1_0, ref __arg_1_1, ref __arg_1_2),
402                 ) => match Ord::cmp(__self_0, __arg_1_0) {
403                     Ordering::Equal => match Ord::cmp(__self_1, __arg_1_1) {
404                         Ordering::Equal => Ord::cmp(__self_2, __arg_1_2),
405                         cmp => cmp,
406                     },
407                     cmp => cmp,
408                 },
409                 (&GeneratorWitness(ref __self_0), &GeneratorWitness(ref __arg_1_0)) => {
410                     Ord::cmp(__self_0, __arg_1_0)
411                 }
412                 (&Tuple(ref __self_0), &Tuple(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
413                 (&Projection(ref __self_0), &Projection(ref __arg_1_0)) => {
414                     Ord::cmp(__self_0, __arg_1_0)
415                 }
416                 (&Opaque(ref __self_0, ref __self_1), &Opaque(ref __arg_1_0, ref __arg_1_1)) => {
417                     match Ord::cmp(__self_0, __arg_1_0) {
418                         Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
419                         cmp => cmp,
420                     }
421                 }
422                 (&Param(ref __self_0), &Param(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
423                 (&Bound(ref __self_0, ref __self_1), &Bound(ref __arg_1_0, ref __arg_1_1)) => {
424                     match Ord::cmp(__self_0, __arg_1_0) {
425                         Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
426                         cmp => cmp,
427                     }
428                 }
429                 (&Placeholder(ref __self_0), &Placeholder(ref __arg_1_0)) => {
430                     Ord::cmp(__self_0, __arg_1_0)
431                 }
432                 (&Infer(ref __self_0), &Infer(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
433                 (&Error(ref __self_0), &Error(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
434                 _ => Ordering::Equal,
435             }
436         } else {
437             Ord::cmp(&__self_vi, &__arg_1_vi)
438         }
439     }
440 }
441
442 // This is manually implemented because a derive would require `I: Hash`
443 impl<I: Interner> hash::Hash for TyKind<I> {
444     fn hash<__H: hash::Hasher>(&self, state: &mut __H) -> () {
445         match (&*self,) {
446             (&Int(ref __self_0),) => {
447                 hash::Hash::hash(&tykind_discriminant(self), state);
448                 hash::Hash::hash(__self_0, state)
449             }
450             (&Uint(ref __self_0),) => {
451                 hash::Hash::hash(&tykind_discriminant(self), state);
452                 hash::Hash::hash(__self_0, state)
453             }
454             (&Float(ref __self_0),) => {
455                 hash::Hash::hash(&tykind_discriminant(self), state);
456                 hash::Hash::hash(__self_0, state)
457             }
458             (&Adt(ref __self_0, ref __self_1),) => {
459                 hash::Hash::hash(&tykind_discriminant(self), state);
460                 hash::Hash::hash(__self_0, state);
461                 hash::Hash::hash(__self_1, state)
462             }
463             (&Foreign(ref __self_0),) => {
464                 hash::Hash::hash(&tykind_discriminant(self), state);
465                 hash::Hash::hash(__self_0, state)
466             }
467             (&Array(ref __self_0, ref __self_1),) => {
468                 hash::Hash::hash(&tykind_discriminant(self), state);
469                 hash::Hash::hash(__self_0, state);
470                 hash::Hash::hash(__self_1, state)
471             }
472             (&Slice(ref __self_0),) => {
473                 hash::Hash::hash(&tykind_discriminant(self), state);
474                 hash::Hash::hash(__self_0, state)
475             }
476             (&RawPtr(ref __self_0),) => {
477                 hash::Hash::hash(&tykind_discriminant(self), state);
478                 hash::Hash::hash(__self_0, state)
479             }
480             (&Ref(ref __self_0, ref __self_1, ref __self_2),) => {
481                 hash::Hash::hash(&tykind_discriminant(self), state);
482                 hash::Hash::hash(__self_0, state);
483                 hash::Hash::hash(__self_1, state);
484                 hash::Hash::hash(__self_2, state)
485             }
486             (&FnDef(ref __self_0, ref __self_1),) => {
487                 hash::Hash::hash(&tykind_discriminant(self), state);
488                 hash::Hash::hash(__self_0, state);
489                 hash::Hash::hash(__self_1, state)
490             }
491             (&FnPtr(ref __self_0),) => {
492                 hash::Hash::hash(&tykind_discriminant(self), state);
493                 hash::Hash::hash(__self_0, state)
494             }
495             (&Dynamic(ref __self_0, ref __self_1),) => {
496                 hash::Hash::hash(&tykind_discriminant(self), state);
497                 hash::Hash::hash(__self_0, state);
498                 hash::Hash::hash(__self_1, state)
499             }
500             (&Closure(ref __self_0, ref __self_1),) => {
501                 hash::Hash::hash(&tykind_discriminant(self), state);
502                 hash::Hash::hash(__self_0, state);
503                 hash::Hash::hash(__self_1, state)
504             }
505             (&Generator(ref __self_0, ref __self_1, ref __self_2),) => {
506                 hash::Hash::hash(&tykind_discriminant(self), state);
507                 hash::Hash::hash(__self_0, state);
508                 hash::Hash::hash(__self_1, state);
509                 hash::Hash::hash(__self_2, state)
510             }
511             (&GeneratorWitness(ref __self_0),) => {
512                 hash::Hash::hash(&tykind_discriminant(self), state);
513                 hash::Hash::hash(__self_0, state)
514             }
515             (&Tuple(ref __self_0),) => {
516                 hash::Hash::hash(&tykind_discriminant(self), state);
517                 hash::Hash::hash(__self_0, state)
518             }
519             (&Projection(ref __self_0),) => {
520                 hash::Hash::hash(&tykind_discriminant(self), state);
521                 hash::Hash::hash(__self_0, state)
522             }
523             (&Opaque(ref __self_0, ref __self_1),) => {
524                 hash::Hash::hash(&tykind_discriminant(self), state);
525                 hash::Hash::hash(__self_0, state);
526                 hash::Hash::hash(__self_1, state)
527             }
528             (&Param(ref __self_0),) => {
529                 hash::Hash::hash(&tykind_discriminant(self), state);
530                 hash::Hash::hash(__self_0, state)
531             }
532             (&Bound(ref __self_0, ref __self_1),) => {
533                 hash::Hash::hash(&tykind_discriminant(self), state);
534                 hash::Hash::hash(__self_0, state);
535                 hash::Hash::hash(__self_1, state)
536             }
537             (&Placeholder(ref __self_0),) => {
538                 hash::Hash::hash(&tykind_discriminant(self), state);
539                 hash::Hash::hash(__self_0, state)
540             }
541             (&Infer(ref __self_0),) => {
542                 hash::Hash::hash(&tykind_discriminant(self), state);
543                 hash::Hash::hash(__self_0, state)
544             }
545             (&Error(ref __self_0),) => {
546                 hash::Hash::hash(&tykind_discriminant(self), state);
547                 hash::Hash::hash(__self_0, state)
548             }
549             _ => hash::Hash::hash(&tykind_discriminant(self), state),
550         }
551     }
552 }
553
554 // This is manually implemented because a derive would require `I: Debug`
555 impl<I: Interner> fmt::Debug for TyKind<I> {
556     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
557         use std::fmt::*;
558         match self {
559             Bool => Formatter::write_str(f, "Bool"),
560             Char => Formatter::write_str(f, "Char"),
561             Int(f0) => Formatter::debug_tuple_field1_finish(f, "Int", f0),
562             Uint(f0) => Formatter::debug_tuple_field1_finish(f, "Uint", f0),
563             Float(f0) => Formatter::debug_tuple_field1_finish(f, "Float", f0),
564             Adt(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Adt", f0, f1),
565             Foreign(f0) => Formatter::debug_tuple_field1_finish(f, "Foreign", f0),
566             Str => Formatter::write_str(f, "Str"),
567             Array(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Array", f0, f1),
568             Slice(f0) => Formatter::debug_tuple_field1_finish(f, "Slice", f0),
569             RawPtr(f0) => Formatter::debug_tuple_field1_finish(f, "RawPtr", f0),
570             Ref(f0, f1, f2) => Formatter::debug_tuple_field3_finish(f, "Ref", f0, f1, f2),
571             FnDef(f0, f1) => Formatter::debug_tuple_field2_finish(f, "FnDef", f0, f1),
572             FnPtr(f0) => Formatter::debug_tuple_field1_finish(f, "FnPtr", f0),
573             Dynamic(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Dynamic", f0, f1),
574             Closure(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Closure", f0, f1),
575             Generator(f0, f1, f2) => {
576                 Formatter::debug_tuple_field3_finish(f, "Generator", f0, f1, f2)
577             }
578             GeneratorWitness(f0) => Formatter::debug_tuple_field1_finish(f, "GeneratorWitness", f0),
579             Never => Formatter::write_str(f, "Never"),
580             Tuple(f0) => Formatter::debug_tuple_field1_finish(f, "Tuple", f0),
581             Projection(f0) => Formatter::debug_tuple_field1_finish(f, "Projection", f0),
582             Opaque(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Opaque", f0, f1),
583             Param(f0) => Formatter::debug_tuple_field1_finish(f, "Param", f0),
584             Bound(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Bound", f0, f1),
585             Placeholder(f0) => Formatter::debug_tuple_field1_finish(f, "Placeholder", f0),
586             Infer(f0) => Formatter::debug_tuple_field1_finish(f, "Infer", f0),
587             TyKind::Error(f0) => Formatter::debug_tuple_field1_finish(f, "Error", f0),
588         }
589     }
590 }
591
592 // This is manually implemented because a derive would require `I: Encodable`
593 impl<I: Interner, E: TyEncoder> Encodable<E> for TyKind<I>
594 where
595     I::DelaySpanBugEmitted: Encodable<E>,
596     I::AdtDef: Encodable<E>,
597     I::SubstsRef: Encodable<E>,
598     I::DefId: Encodable<E>,
599     I::Ty: Encodable<E>,
600     I::Const: Encodable<E>,
601     I::Region: Encodable<E>,
602     I::TypeAndMut: Encodable<E>,
603     I::Mutability: Encodable<E>,
604     I::Movability: Encodable<E>,
605     I::PolyFnSig: Encodable<E>,
606     I::ListBinderExistentialPredicate: Encodable<E>,
607     I::BinderListTy: Encodable<E>,
608     I::ListTy: Encodable<E>,
609     I::ProjectionTy: Encodable<E>,
610     I::ParamTy: Encodable<E>,
611     I::BoundTy: Encodable<E>,
612     I::PlaceholderType: Encodable<E>,
613     I::InferTy: Encodable<E>,
614     I::DelaySpanBugEmitted: Encodable<E>,
615     I::PredicateKind: Encodable<E>,
616     I::AllocId: Encodable<E>,
617 {
618     fn encode(&self, e: &mut E) {
619         let disc = tykind_discriminant(self);
620         match self {
621             Bool => e.emit_enum_variant(disc, |_| {}),
622             Char => e.emit_enum_variant(disc, |_| {}),
623             Int(i) => e.emit_enum_variant(disc, |e| {
624                 i.encode(e);
625             }),
626             Uint(u) => e.emit_enum_variant(disc, |e| {
627                 u.encode(e);
628             }),
629             Float(f) => e.emit_enum_variant(disc, |e| {
630                 f.encode(e);
631             }),
632             Adt(adt, substs) => e.emit_enum_variant(disc, |e| {
633                 adt.encode(e);
634                 substs.encode(e);
635             }),
636             Foreign(def_id) => e.emit_enum_variant(disc, |e| {
637                 def_id.encode(e);
638             }),
639             Str => e.emit_enum_variant(disc, |_| {}),
640             Array(t, c) => e.emit_enum_variant(disc, |e| {
641                 t.encode(e);
642                 c.encode(e);
643             }),
644             Slice(t) => e.emit_enum_variant(disc, |e| {
645                 t.encode(e);
646             }),
647             RawPtr(tam) => e.emit_enum_variant(disc, |e| {
648                 tam.encode(e);
649             }),
650             Ref(r, t, m) => e.emit_enum_variant(disc, |e| {
651                 r.encode(e);
652                 t.encode(e);
653                 m.encode(e);
654             }),
655             FnDef(def_id, substs) => e.emit_enum_variant(disc, |e| {
656                 def_id.encode(e);
657                 substs.encode(e);
658             }),
659             FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| {
660                 polyfnsig.encode(e);
661             }),
662             Dynamic(l, r) => e.emit_enum_variant(disc, |e| {
663                 l.encode(e);
664                 r.encode(e);
665             }),
666             Closure(def_id, substs) => e.emit_enum_variant(disc, |e| {
667                 def_id.encode(e);
668                 substs.encode(e);
669             }),
670             Generator(def_id, substs, m) => e.emit_enum_variant(disc, |e| {
671                 def_id.encode(e);
672                 substs.encode(e);
673                 m.encode(e);
674             }),
675             GeneratorWitness(b) => e.emit_enum_variant(disc, |e| {
676                 b.encode(e);
677             }),
678             Never => e.emit_enum_variant(disc, |_| {}),
679             Tuple(substs) => e.emit_enum_variant(disc, |e| {
680                 substs.encode(e);
681             }),
682             Projection(p) => e.emit_enum_variant(disc, |e| {
683                 p.encode(e);
684             }),
685             Opaque(def_id, substs) => e.emit_enum_variant(disc, |e| {
686                 def_id.encode(e);
687                 substs.encode(e);
688             }),
689             Param(p) => e.emit_enum_variant(disc, |e| {
690                 p.encode(e);
691             }),
692             Bound(d, b) => e.emit_enum_variant(disc, |e| {
693                 d.encode(e);
694                 b.encode(e);
695             }),
696             Placeholder(p) => e.emit_enum_variant(disc, |e| {
697                 p.encode(e);
698             }),
699             Infer(i) => e.emit_enum_variant(disc, |e| {
700                 i.encode(e);
701             }),
702             Error(d) => e.emit_enum_variant(disc, |e| {
703                 d.encode(e);
704             }),
705         }
706     }
707 }
708
709 // This is manually implemented because a derive would require `I: Decodable`
710 impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for TyKind<I>
711 where
712     I::DelaySpanBugEmitted: Decodable<D>,
713     I::AdtDef: Decodable<D>,
714     I::SubstsRef: Decodable<D>,
715     I::DefId: Decodable<D>,
716     I::Ty: Decodable<D>,
717     I::Const: Decodable<D>,
718     I::Region: Decodable<D>,
719     I::TypeAndMut: Decodable<D>,
720     I::Mutability: Decodable<D>,
721     I::Movability: Decodable<D>,
722     I::PolyFnSig: Decodable<D>,
723     I::ListBinderExistentialPredicate: Decodable<D>,
724     I::BinderListTy: Decodable<D>,
725     I::ListTy: Decodable<D>,
726     I::ProjectionTy: Decodable<D>,
727     I::ParamTy: Decodable<D>,
728     I::BoundTy: Decodable<D>,
729     I::PlaceholderType: Decodable<D>,
730     I::InferTy: Decodable<D>,
731     I::DelaySpanBugEmitted: Decodable<D>,
732     I::PredicateKind: Decodable<D>,
733     I::AllocId: Decodable<D>,
734 {
735     fn decode(d: &mut D) -> Self {
736         match Decoder::read_usize(d) {
737             0 => Bool,
738             1 => Char,
739             2 => Int(Decodable::decode(d)),
740             3 => Uint(Decodable::decode(d)),
741             4 => Float(Decodable::decode(d)),
742             5 => Adt(Decodable::decode(d), Decodable::decode(d)),
743             6 => Foreign(Decodable::decode(d)),
744             7 => Str,
745             8 => Array(Decodable::decode(d), Decodable::decode(d)),
746             9 => Slice(Decodable::decode(d)),
747             10 => RawPtr(Decodable::decode(d)),
748             11 => Ref(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
749             12 => FnDef(Decodable::decode(d), Decodable::decode(d)),
750             13 => FnPtr(Decodable::decode(d)),
751             14 => Dynamic(Decodable::decode(d), Decodable::decode(d)),
752             15 => Closure(Decodable::decode(d), Decodable::decode(d)),
753             16 => Generator(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
754             17 => GeneratorWitness(Decodable::decode(d)),
755             18 => Never,
756             19 => Tuple(Decodable::decode(d)),
757             20 => Projection(Decodable::decode(d)),
758             21 => Opaque(Decodable::decode(d), Decodable::decode(d)),
759             22 => Param(Decodable::decode(d)),
760             23 => Bound(Decodable::decode(d), Decodable::decode(d)),
761             24 => Placeholder(Decodable::decode(d)),
762             25 => Infer(Decodable::decode(d)),
763             26 => Error(Decodable::decode(d)),
764             _ => panic!(
765                 "{}",
766                 format!(
767                     "invalid enum variant tag while decoding `{}`, expected 0..{}",
768                     "TyKind", 27,
769                 )
770             ),
771         }
772     }
773 }
774
775 // This is not a derived impl because a derive would require `I: HashStable`
776 #[allow(rustc::usage_of_ty_tykind)]
777 impl<CTX, I: Interner> HashStable<CTX> for TyKind<I>
778 where
779     I::AdtDef: HashStable<CTX>,
780     I::DefId: HashStable<CTX>,
781     I::SubstsRef: HashStable<CTX>,
782     I::Ty: HashStable<CTX>,
783     I::Const: HashStable<CTX>,
784     I::TypeAndMut: HashStable<CTX>,
785     I::PolyFnSig: HashStable<CTX>,
786     I::ListBinderExistentialPredicate: HashStable<CTX>,
787     I::Region: HashStable<CTX>,
788     I::Movability: HashStable<CTX>,
789     I::Mutability: HashStable<CTX>,
790     I::BinderListTy: HashStable<CTX>,
791     I::ListTy: HashStable<CTX>,
792     I::ProjectionTy: HashStable<CTX>,
793     I::BoundTy: HashStable<CTX>,
794     I::ParamTy: HashStable<CTX>,
795     I::PlaceholderType: HashStable<CTX>,
796     I::InferTy: HashStable<CTX>,
797     I::DelaySpanBugEmitted: HashStable<CTX>,
798 {
799     #[inline]
800     fn hash_stable(
801         &self,
802         __hcx: &mut CTX,
803         __hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
804     ) {
805         std::mem::discriminant(self).hash_stable(__hcx, __hasher);
806         match self {
807             Bool => {}
808             Char => {}
809             Int(i) => {
810                 i.hash_stable(__hcx, __hasher);
811             }
812             Uint(u) => {
813                 u.hash_stable(__hcx, __hasher);
814             }
815             Float(f) => {
816                 f.hash_stable(__hcx, __hasher);
817             }
818             Adt(adt, substs) => {
819                 adt.hash_stable(__hcx, __hasher);
820                 substs.hash_stable(__hcx, __hasher);
821             }
822             Foreign(def_id) => {
823                 def_id.hash_stable(__hcx, __hasher);
824             }
825             Str => {}
826             Array(t, c) => {
827                 t.hash_stable(__hcx, __hasher);
828                 c.hash_stable(__hcx, __hasher);
829             }
830             Slice(t) => {
831                 t.hash_stable(__hcx, __hasher);
832             }
833             RawPtr(tam) => {
834                 tam.hash_stable(__hcx, __hasher);
835             }
836             Ref(r, t, m) => {
837                 r.hash_stable(__hcx, __hasher);
838                 t.hash_stable(__hcx, __hasher);
839                 m.hash_stable(__hcx, __hasher);
840             }
841             FnDef(def_id, substs) => {
842                 def_id.hash_stable(__hcx, __hasher);
843                 substs.hash_stable(__hcx, __hasher);
844             }
845             FnPtr(polyfnsig) => {
846                 polyfnsig.hash_stable(__hcx, __hasher);
847             }
848             Dynamic(l, r) => {
849                 l.hash_stable(__hcx, __hasher);
850                 r.hash_stable(__hcx, __hasher);
851             }
852             Closure(def_id, substs) => {
853                 def_id.hash_stable(__hcx, __hasher);
854                 substs.hash_stable(__hcx, __hasher);
855             }
856             Generator(def_id, substs, m) => {
857                 def_id.hash_stable(__hcx, __hasher);
858                 substs.hash_stable(__hcx, __hasher);
859                 m.hash_stable(__hcx, __hasher);
860             }
861             GeneratorWitness(b) => {
862                 b.hash_stable(__hcx, __hasher);
863             }
864             Never => {}
865             Tuple(substs) => {
866                 substs.hash_stable(__hcx, __hasher);
867             }
868             Projection(p) => {
869                 p.hash_stable(__hcx, __hasher);
870             }
871             Opaque(def_id, substs) => {
872                 def_id.hash_stable(__hcx, __hasher);
873                 substs.hash_stable(__hcx, __hasher);
874             }
875             Param(p) => {
876                 p.hash_stable(__hcx, __hasher);
877             }
878             Bound(d, b) => {
879                 d.hash_stable(__hcx, __hasher);
880                 b.hash_stable(__hcx, __hasher);
881             }
882             Placeholder(p) => {
883                 p.hash_stable(__hcx, __hasher);
884             }
885             Infer(i) => {
886                 i.hash_stable(__hcx, __hasher);
887             }
888             Error(d) => {
889                 d.hash_stable(__hcx, __hasher);
890             }
891         }
892     }
893 }
894
895 /// Representation of regions. Note that the NLL checker uses a distinct
896 /// representation of regions. For this reason, it internally replaces all the
897 /// regions with inference variables -- the index of the variable is then used
898 /// to index into internal NLL data structures. See `rustc_const_eval::borrow_check`
899 /// module for more information.
900 ///
901 /// Note: operations are on the wrapper `Region` type, which is interned,
902 /// rather than this type.
903 ///
904 /// ## The Region lattice within a given function
905 ///
906 /// In general, the region lattice looks like
907 ///
908 /// ```text
909 /// static ----------+-----...------+       (greatest)
910 /// |                |              |
911 /// early-bound and  |              |
912 /// free regions     |              |
913 /// |                |              |
914 /// |                |              |
915 /// empty(root)   placeholder(U1)   |
916 /// |            /                  |
917 /// |           /         placeholder(Un)
918 /// empty(U1) --         /
919 /// |                   /
920 /// ...                /
921 /// |                 /
922 /// empty(Un) --------                      (smallest)
923 /// ```
924 ///
925 /// Early-bound/free regions are the named lifetimes in scope from the
926 /// function declaration. They have relationships to one another
927 /// determined based on the declared relationships from the
928 /// function.
929 ///
930 /// Note that inference variables and bound regions are not included
931 /// in this diagram. In the case of inference variables, they should
932 /// be inferred to some other region from the diagram.  In the case of
933 /// bound regions, they are excluded because they don't make sense to
934 /// include -- the diagram indicates the relationship between free
935 /// regions.
936 ///
937 /// ## Inference variables
938 ///
939 /// During region inference, we sometimes create inference variables,
940 /// represented as `ReVar`. These will be inferred by the code in
941 /// `infer::lexical_region_resolve` to some free region from the
942 /// lattice above (the minimal region that meets the
943 /// constraints).
944 ///
945 /// During NLL checking, where regions are defined differently, we
946 /// also use `ReVar` -- in that case, the index is used to index into
947 /// the NLL region checker's data structures. The variable may in fact
948 /// represent either a free region or an inference variable, in that
949 /// case.
950 ///
951 /// ## Bound Regions
952 ///
953 /// These are regions that are stored behind a binder and must be substituted
954 /// with some concrete region before being used. There are two kind of
955 /// bound regions: early-bound, which are bound in an item's `Generics`,
956 /// and are substituted by an `InternalSubsts`, and late-bound, which are part of
957 /// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by
958 /// the likes of `liberate_late_bound_regions`. The distinction exists
959 /// because higher-ranked lifetimes aren't supported in all places. See [1][2].
960 ///
961 /// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
962 /// outside their binder, e.g., in types passed to type inference, and
963 /// should first be substituted (by placeholder regions, free regions,
964 /// or region variables).
965 ///
966 /// ## Placeholder and Free Regions
967 ///
968 /// One often wants to work with bound regions without knowing their precise
969 /// identity. For example, when checking a function, the lifetime of a borrow
970 /// can end up being assigned to some region parameter. In these cases,
971 /// it must be ensured that bounds on the region can't be accidentally
972 /// assumed without being checked.
973 ///
974 /// To do this, we replace the bound regions with placeholder markers,
975 /// which don't satisfy any relation not explicitly provided.
976 ///
977 /// There are two kinds of placeholder regions in rustc: `ReFree` and
978 /// `RePlaceholder`. When checking an item's body, `ReFree` is supposed
979 /// to be used. These also support explicit bounds: both the internally-stored
980 /// *scope*, which the region is assumed to outlive, as well as other
981 /// relations stored in the `FreeRegionMap`. Note that these relations
982 /// aren't checked when you `make_subregion` (or `eq_types`), only by
983 /// `resolve_regions_and_report_errors`.
984 ///
985 /// When working with higher-ranked types, some region relations aren't
986 /// yet known, so you can't just call `resolve_regions_and_report_errors`.
987 /// `RePlaceholder` is designed for this purpose. In these contexts,
988 /// there's also the risk that some inference variable laying around will
989 /// get unified with your placeholder region: if you want to check whether
990 /// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
991 /// with a placeholder region `'%a`, the variable `'_` would just be
992 /// instantiated to the placeholder region `'%a`, which is wrong because
993 /// the inference variable is supposed to satisfy the relation
994 /// *for every value of the placeholder region*. To ensure that doesn't
995 /// happen, you can use `leak_check`. This is more clearly explained
996 /// by the [rustc dev guide].
997 ///
998 /// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
999 /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
1000 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
1001 pub enum RegionKind<I: Interner> {
1002     /// Region bound in a type or fn declaration which will be
1003     /// substituted 'early' -- that is, at the same time when type
1004     /// parameters are substituted.
1005     ReEarlyBound(I::EarlyBoundRegion),
1006
1007     /// Region bound in a function scope, which will be substituted when the
1008     /// function is called.
1009     ReLateBound(DebruijnIndex, I::BoundRegion),
1010
1011     /// When checking a function body, the types of all arguments and so forth
1012     /// that refer to bound region parameters are modified to refer to free
1013     /// region parameters.
1014     ReFree(I::FreeRegion),
1015
1016     /// Static data that has an "infinite" lifetime. Top in the region lattice.
1017     ReStatic,
1018
1019     /// A region variable. Should not exist outside of type inference.
1020     ReVar(I::RegionVid),
1021
1022     /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
1023     /// Should not exist outside of type inference.
1024     RePlaceholder(I::PlaceholderRegion),
1025
1026     /// Empty lifetime is for data that is never accessed.  We tag the
1027     /// empty lifetime with a universe -- the idea is that we don't
1028     /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
1029     /// Therefore, the `'empty` in a universe `U` is less than all
1030     /// regions visible from `U`, but not less than regions not visible
1031     /// from `U`.
1032     ReEmpty(UniverseIndex),
1033
1034     /// Erased region, used by trait selection, in MIR and during codegen.
1035     ReErased,
1036 }
1037
1038 // This is manually implemented for `RegionKind` because `std::mem::discriminant`
1039 // returns an opaque value that is `PartialEq` but not `PartialOrd`
1040 #[inline]
1041 const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
1042     match value {
1043         ReEarlyBound(_) => 0,
1044         ReLateBound(_, _) => 1,
1045         ReFree(_) => 2,
1046         ReStatic => 3,
1047         ReVar(_) => 4,
1048         RePlaceholder(_) => 5,
1049         ReEmpty(_) => 6,
1050         ReErased => 7,
1051     }
1052 }
1053
1054 // This is manually implemented because a derive would require `I: Copy`
1055 impl<I: Interner> Copy for RegionKind<I>
1056 where
1057     I::EarlyBoundRegion: Copy,
1058     I::BoundRegion: Copy,
1059     I::FreeRegion: Copy,
1060     I::RegionVid: Copy,
1061     I::PlaceholderRegion: Copy,
1062 {
1063 }
1064
1065 // This is manually implemented because a derive would require `I: Clone`
1066 impl<I: Interner> Clone for RegionKind<I> {
1067     fn clone(&self) -> Self {
1068         match self {
1069             ReEarlyBound(a) => ReEarlyBound(a.clone()),
1070             ReLateBound(a, b) => ReLateBound(a.clone(), b.clone()),
1071             ReFree(a) => ReFree(a.clone()),
1072             ReStatic => ReStatic,
1073             ReVar(a) => ReVar(a.clone()),
1074             RePlaceholder(a) => RePlaceholder(a.clone()),
1075             ReEmpty(a) => ReEmpty(a.clone()),
1076             ReErased => ReErased,
1077         }
1078     }
1079 }
1080
1081 // This is manually implemented because a derive would require `I: PartialEq`
1082 impl<I: Interner> PartialEq for RegionKind<I> {
1083     #[inline]
1084     fn eq(&self, other: &RegionKind<I>) -> bool {
1085         let __self_vi = regionkind_discriminant(self);
1086         let __arg_1_vi = regionkind_discriminant(other);
1087         if __self_vi == __arg_1_vi {
1088             match (&*self, &*other) {
1089                 (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
1090                     __self_0 == __arg_1_0
1091                 }
1092                 (
1093                     &ReLateBound(ref __self_0, ref __self_1),
1094                     &ReLateBound(ref __arg_1_0, ref __arg_1_1),
1095                 ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1,
1096                 (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => __self_0 == __arg_1_0,
1097                 (&ReStatic, &ReStatic) => true,
1098                 (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => __self_0 == __arg_1_0,
1099                 (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
1100                     __self_0 == __arg_1_0
1101                 }
1102                 (&ReEmpty(ref __self_0), &ReEmpty(ref __arg_1_0)) => __self_0 == __arg_1_0,
1103                 (&ReErased, &ReErased) => true,
1104                 _ => true,
1105             }
1106         } else {
1107             false
1108         }
1109     }
1110 }
1111
1112 // This is manually implemented because a derive would require `I: Eq`
1113 impl<I: Interner> Eq for RegionKind<I> {}
1114
1115 // This is manually implemented because a derive would require `I: PartialOrd`
1116 impl<I: Interner> PartialOrd for RegionKind<I> {
1117     #[inline]
1118     fn partial_cmp(&self, other: &RegionKind<I>) -> Option<Ordering> {
1119         Some(Ord::cmp(self, other))
1120     }
1121 }
1122
1123 // This is manually implemented because a derive would require `I: Ord`
1124 impl<I: Interner> Ord for RegionKind<I> {
1125     #[inline]
1126     fn cmp(&self, other: &RegionKind<I>) -> Ordering {
1127         let __self_vi = regionkind_discriminant(self);
1128         let __arg_1_vi = regionkind_discriminant(other);
1129         if __self_vi == __arg_1_vi {
1130             match (&*self, &*other) {
1131                 (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
1132                     Ord::cmp(__self_0, __arg_1_0)
1133                 }
1134                 (
1135                     &ReLateBound(ref __self_0, ref __self_1),
1136                     &ReLateBound(ref __arg_1_0, ref __arg_1_1),
1137                 ) => match Ord::cmp(__self_0, __arg_1_0) {
1138                     Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
1139                     cmp => cmp,
1140                 },
1141                 (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
1142                 (&ReStatic, &ReStatic) => Ordering::Equal,
1143                 (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
1144                 (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
1145                     Ord::cmp(__self_0, __arg_1_0)
1146                 }
1147                 (&ReEmpty(ref __self_0), &ReEmpty(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
1148                 (&ReErased, &ReErased) => Ordering::Equal,
1149                 _ => Ordering::Equal,
1150             }
1151         } else {
1152             Ord::cmp(&__self_vi, &__arg_1_vi)
1153         }
1154     }
1155 }
1156
1157 // This is manually implemented because a derive would require `I: Hash`
1158 impl<I: Interner> hash::Hash for RegionKind<I> {
1159     fn hash<__H: hash::Hasher>(&self, state: &mut __H) -> () {
1160         match (&*self,) {
1161             (&ReEarlyBound(ref __self_0),) => {
1162                 hash::Hash::hash(&regionkind_discriminant(self), state);
1163                 hash::Hash::hash(__self_0, state)
1164             }
1165             (&ReLateBound(ref __self_0, ref __self_1),) => {
1166                 hash::Hash::hash(&regionkind_discriminant(self), state);
1167                 hash::Hash::hash(__self_0, state);
1168                 hash::Hash::hash(__self_1, state)
1169             }
1170             (&ReFree(ref __self_0),) => {
1171                 hash::Hash::hash(&regionkind_discriminant(self), state);
1172                 hash::Hash::hash(__self_0, state)
1173             }
1174             (&ReStatic,) => {
1175                 hash::Hash::hash(&regionkind_discriminant(self), state);
1176             }
1177             (&ReVar(ref __self_0),) => {
1178                 hash::Hash::hash(&regionkind_discriminant(self), state);
1179                 hash::Hash::hash(__self_0, state)
1180             }
1181             (&RePlaceholder(ref __self_0),) => {
1182                 hash::Hash::hash(&regionkind_discriminant(self), state);
1183                 hash::Hash::hash(__self_0, state)
1184             }
1185             (&ReEmpty(ref __self_0),) => {
1186                 hash::Hash::hash(&regionkind_discriminant(self), state);
1187                 hash::Hash::hash(__self_0, state)
1188             }
1189             (&ReErased,) => {
1190                 hash::Hash::hash(&regionkind_discriminant(self), state);
1191             }
1192         }
1193     }
1194 }
1195
1196 // This is manually implemented because a derive would require `I: Debug`
1197 impl<I: Interner> fmt::Debug for RegionKind<I> {
1198     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1199         match self {
1200             ReEarlyBound(ref data) => write!(f, "ReEarlyBound({:?})", data),
1201
1202             ReLateBound(binder_id, ref bound_region) => {
1203                 write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
1204             }
1205
1206             ReFree(ref fr) => fr.fmt(f),
1207
1208             ReStatic => write!(f, "ReStatic"),
1209
1210             ReVar(ref vid) => vid.fmt(f),
1211
1212             RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
1213
1214             ReEmpty(ui) => write!(f, "ReEmpty({:?})", ui),
1215
1216             ReErased => write!(f, "ReErased"),
1217         }
1218     }
1219 }
1220
1221 // This is manually implemented because a derive would require `I: Encodable`
1222 impl<I: Interner, E: TyEncoder> Encodable<E> for RegionKind<I>
1223 where
1224     I::EarlyBoundRegion: Encodable<E>,
1225     I::BoundRegion: Encodable<E>,
1226     I::FreeRegion: Encodable<E>,
1227     I::RegionVid: Encodable<E>,
1228     I::PlaceholderRegion: Encodable<E>,
1229 {
1230     fn encode(&self, e: &mut E) {
1231         let disc = regionkind_discriminant(self);
1232         match self {
1233             ReEarlyBound(a) => e.emit_enum_variant(disc, |e| {
1234                 a.encode(e);
1235             }),
1236             ReLateBound(a, b) => e.emit_enum_variant(disc, |e| {
1237                 a.encode(e);
1238                 b.encode(e);
1239             }),
1240             ReFree(a) => e.emit_enum_variant(disc, |e| {
1241                 a.encode(e);
1242             }),
1243             ReStatic => e.emit_enum_variant(disc, |_| {}),
1244             ReVar(a) => e.emit_enum_variant(disc, |e| {
1245                 a.encode(e);
1246             }),
1247             RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
1248                 a.encode(e);
1249             }),
1250             ReEmpty(a) => e.emit_enum_variant(disc, |e| {
1251                 a.encode(e);
1252             }),
1253             ReErased => e.emit_enum_variant(disc, |_| {}),
1254         }
1255     }
1256 }
1257
1258 // This is manually implemented because a derive would require `I: Decodable`
1259 impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for RegionKind<I>
1260 where
1261     I::EarlyBoundRegion: Decodable<D>,
1262     I::BoundRegion: Decodable<D>,
1263     I::FreeRegion: Decodable<D>,
1264     I::RegionVid: Decodable<D>,
1265     I::PlaceholderRegion: Decodable<D>,
1266 {
1267     fn decode(d: &mut D) -> Self {
1268         match Decoder::read_usize(d) {
1269             0 => ReEarlyBound(Decodable::decode(d)),
1270             1 => ReLateBound(Decodable::decode(d), Decodable::decode(d)),
1271             2 => ReFree(Decodable::decode(d)),
1272             3 => ReStatic,
1273             4 => ReVar(Decodable::decode(d)),
1274             5 => RePlaceholder(Decodable::decode(d)),
1275             6 => ReEmpty(Decodable::decode(d)),
1276             7 => ReErased,
1277             _ => panic!(
1278                 "{}",
1279                 format!(
1280                     "invalid enum variant tag while decoding `{}`, expected 0..{}",
1281                     "RegionKind", 8,
1282                 )
1283             ),
1284         }
1285     }
1286 }
1287
1288 // This is not a derived impl because a derive would require `I: HashStable`
1289 impl<CTX, I: Interner> HashStable<CTX> for RegionKind<I>
1290 where
1291     I::EarlyBoundRegion: HashStable<CTX>,
1292     I::BoundRegion: HashStable<CTX>,
1293     I::FreeRegion: HashStable<CTX>,
1294     I::RegionVid: HashStable<CTX>,
1295     I::PlaceholderRegion: HashStable<CTX>,
1296 {
1297     #[inline]
1298     fn hash_stable(
1299         &self,
1300         hcx: &mut CTX,
1301         hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
1302     ) {
1303         std::mem::discriminant(self).hash_stable(hcx, hasher);
1304         match self {
1305             ReErased | ReStatic => {
1306                 // No variant fields to hash for these ...
1307             }
1308             ReEmpty(universe) => {
1309                 universe.hash_stable(hcx, hasher);
1310             }
1311             ReLateBound(db, br) => {
1312                 db.hash_stable(hcx, hasher);
1313                 br.hash_stable(hcx, hasher);
1314             }
1315             ReEarlyBound(eb) => {
1316                 eb.hash_stable(hcx, hasher);
1317             }
1318             ReFree(ref free_region) => {
1319                 free_region.hash_stable(hcx, hasher);
1320             }
1321             RePlaceholder(p) => {
1322                 p.hash_stable(hcx, hasher);
1323             }
1324             ReVar(reg) => {
1325                 reg.hash_stable(hcx, hasher);
1326             }
1327         }
1328     }
1329 }