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