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