]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_type_ir/src/sty.rs
Rollup merge of #103396 - RalfJung:pinning-closure-captures, r=dtolnay
[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::ErrorGuaranteed),
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::ErrorGuaranteed: 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::PredicateKind: Encodable<E>,
649     I::AllocId: Encodable<E>,
650 {
651     fn encode(&self, e: &mut E) {
652         let disc = tykind_discriminant(self);
653         match self {
654             Bool => e.emit_enum_variant(disc, |_| {}),
655             Char => e.emit_enum_variant(disc, |_| {}),
656             Int(i) => e.emit_enum_variant(disc, |e| {
657                 i.encode(e);
658             }),
659             Uint(u) => e.emit_enum_variant(disc, |e| {
660                 u.encode(e);
661             }),
662             Float(f) => e.emit_enum_variant(disc, |e| {
663                 f.encode(e);
664             }),
665             Adt(adt, substs) => e.emit_enum_variant(disc, |e| {
666                 adt.encode(e);
667                 substs.encode(e);
668             }),
669             Foreign(def_id) => e.emit_enum_variant(disc, |e| {
670                 def_id.encode(e);
671             }),
672             Str => e.emit_enum_variant(disc, |_| {}),
673             Array(t, c) => e.emit_enum_variant(disc, |e| {
674                 t.encode(e);
675                 c.encode(e);
676             }),
677             Slice(t) => e.emit_enum_variant(disc, |e| {
678                 t.encode(e);
679             }),
680             RawPtr(tam) => e.emit_enum_variant(disc, |e| {
681                 tam.encode(e);
682             }),
683             Ref(r, t, m) => e.emit_enum_variant(disc, |e| {
684                 r.encode(e);
685                 t.encode(e);
686                 m.encode(e);
687             }),
688             FnDef(def_id, substs) => e.emit_enum_variant(disc, |e| {
689                 def_id.encode(e);
690                 substs.encode(e);
691             }),
692             FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| {
693                 polyfnsig.encode(e);
694             }),
695             Dynamic(l, r, repr) => e.emit_enum_variant(disc, |e| {
696                 l.encode(e);
697                 r.encode(e);
698                 repr.encode(e);
699             }),
700             Closure(def_id, substs) => e.emit_enum_variant(disc, |e| {
701                 def_id.encode(e);
702                 substs.encode(e);
703             }),
704             Generator(def_id, substs, m) => e.emit_enum_variant(disc, |e| {
705                 def_id.encode(e);
706                 substs.encode(e);
707                 m.encode(e);
708             }),
709             GeneratorWitness(b) => e.emit_enum_variant(disc, |e| {
710                 b.encode(e);
711             }),
712             Never => e.emit_enum_variant(disc, |_| {}),
713             Tuple(substs) => e.emit_enum_variant(disc, |e| {
714                 substs.encode(e);
715             }),
716             Projection(p) => e.emit_enum_variant(disc, |e| {
717                 p.encode(e);
718             }),
719             Opaque(def_id, substs) => e.emit_enum_variant(disc, |e| {
720                 def_id.encode(e);
721                 substs.encode(e);
722             }),
723             Param(p) => e.emit_enum_variant(disc, |e| {
724                 p.encode(e);
725             }),
726             Bound(d, b) => e.emit_enum_variant(disc, |e| {
727                 d.encode(e);
728                 b.encode(e);
729             }),
730             Placeholder(p) => e.emit_enum_variant(disc, |e| {
731                 p.encode(e);
732             }),
733             Infer(i) => e.emit_enum_variant(disc, |e| {
734                 i.encode(e);
735             }),
736             Error(d) => e.emit_enum_variant(disc, |e| {
737                 d.encode(e);
738             }),
739         }
740     }
741 }
742
743 // This is manually implemented because a derive would require `I: Decodable`
744 impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for TyKind<I>
745 where
746     I::ErrorGuaranteed: Decodable<D>,
747     I::AdtDef: Decodable<D>,
748     I::SubstsRef: Decodable<D>,
749     I::DefId: Decodable<D>,
750     I::Ty: Decodable<D>,
751     I::Const: Decodable<D>,
752     I::Region: Decodable<D>,
753     I::TypeAndMut: Decodable<D>,
754     I::Mutability: Decodable<D>,
755     I::Movability: Decodable<D>,
756     I::PolyFnSig: Decodable<D>,
757     I::ListBinderExistentialPredicate: Decodable<D>,
758     I::BinderListTy: Decodable<D>,
759     I::ListTy: Decodable<D>,
760     I::ProjectionTy: Decodable<D>,
761     I::ParamTy: Decodable<D>,
762     I::BoundTy: Decodable<D>,
763     I::PlaceholderType: Decodable<D>,
764     I::InferTy: Decodable<D>,
765     I::PredicateKind: Decodable<D>,
766     I::AllocId: Decodable<D>,
767 {
768     fn decode(d: &mut D) -> Self {
769         match Decoder::read_usize(d) {
770             0 => Bool,
771             1 => Char,
772             2 => Int(Decodable::decode(d)),
773             3 => Uint(Decodable::decode(d)),
774             4 => Float(Decodable::decode(d)),
775             5 => Adt(Decodable::decode(d), Decodable::decode(d)),
776             6 => Foreign(Decodable::decode(d)),
777             7 => Str,
778             8 => Array(Decodable::decode(d), Decodable::decode(d)),
779             9 => Slice(Decodable::decode(d)),
780             10 => RawPtr(Decodable::decode(d)),
781             11 => Ref(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
782             12 => FnDef(Decodable::decode(d), Decodable::decode(d)),
783             13 => FnPtr(Decodable::decode(d)),
784             14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
785             15 => Closure(Decodable::decode(d), Decodable::decode(d)),
786             16 => Generator(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
787             17 => GeneratorWitness(Decodable::decode(d)),
788             18 => Never,
789             19 => Tuple(Decodable::decode(d)),
790             20 => Projection(Decodable::decode(d)),
791             21 => Opaque(Decodable::decode(d), Decodable::decode(d)),
792             22 => Param(Decodable::decode(d)),
793             23 => Bound(Decodable::decode(d), Decodable::decode(d)),
794             24 => Placeholder(Decodable::decode(d)),
795             25 => Infer(Decodable::decode(d)),
796             26 => Error(Decodable::decode(d)),
797             _ => panic!(
798                 "{}",
799                 format!(
800                     "invalid enum variant tag while decoding `{}`, expected 0..{}",
801                     "TyKind", 27,
802                 )
803             ),
804         }
805     }
806 }
807
808 // This is not a derived impl because a derive would require `I: HashStable`
809 #[allow(rustc::usage_of_ty_tykind)]
810 impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for TyKind<I>
811 where
812     I::AdtDef: HashStable<CTX>,
813     I::DefId: HashStable<CTX>,
814     I::SubstsRef: HashStable<CTX>,
815     I::Ty: HashStable<CTX>,
816     I::Const: HashStable<CTX>,
817     I::TypeAndMut: HashStable<CTX>,
818     I::PolyFnSig: HashStable<CTX>,
819     I::ListBinderExistentialPredicate: HashStable<CTX>,
820     I::Region: HashStable<CTX>,
821     I::Movability: HashStable<CTX>,
822     I::Mutability: HashStable<CTX>,
823     I::BinderListTy: HashStable<CTX>,
824     I::ListTy: HashStable<CTX>,
825     I::ProjectionTy: HashStable<CTX>,
826     I::BoundTy: HashStable<CTX>,
827     I::ParamTy: HashStable<CTX>,
828     I::PlaceholderType: HashStable<CTX>,
829     I::InferTy: HashStable<CTX>,
830     I::ErrorGuaranteed: HashStable<CTX>,
831 {
832     #[inline]
833     fn hash_stable(
834         &self,
835         __hcx: &mut CTX,
836         __hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
837     ) {
838         std::mem::discriminant(self).hash_stable(__hcx, __hasher);
839         match self {
840             Bool => {}
841             Char => {}
842             Int(i) => {
843                 i.hash_stable(__hcx, __hasher);
844             }
845             Uint(u) => {
846                 u.hash_stable(__hcx, __hasher);
847             }
848             Float(f) => {
849                 f.hash_stable(__hcx, __hasher);
850             }
851             Adt(adt, substs) => {
852                 adt.hash_stable(__hcx, __hasher);
853                 substs.hash_stable(__hcx, __hasher);
854             }
855             Foreign(def_id) => {
856                 def_id.hash_stable(__hcx, __hasher);
857             }
858             Str => {}
859             Array(t, c) => {
860                 t.hash_stable(__hcx, __hasher);
861                 c.hash_stable(__hcx, __hasher);
862             }
863             Slice(t) => {
864                 t.hash_stable(__hcx, __hasher);
865             }
866             RawPtr(tam) => {
867                 tam.hash_stable(__hcx, __hasher);
868             }
869             Ref(r, t, m) => {
870                 r.hash_stable(__hcx, __hasher);
871                 t.hash_stable(__hcx, __hasher);
872                 m.hash_stable(__hcx, __hasher);
873             }
874             FnDef(def_id, substs) => {
875                 def_id.hash_stable(__hcx, __hasher);
876                 substs.hash_stable(__hcx, __hasher);
877             }
878             FnPtr(polyfnsig) => {
879                 polyfnsig.hash_stable(__hcx, __hasher);
880             }
881             Dynamic(l, r, repr) => {
882                 l.hash_stable(__hcx, __hasher);
883                 r.hash_stable(__hcx, __hasher);
884                 repr.hash_stable(__hcx, __hasher);
885             }
886             Closure(def_id, substs) => {
887                 def_id.hash_stable(__hcx, __hasher);
888                 substs.hash_stable(__hcx, __hasher);
889             }
890             Generator(def_id, substs, m) => {
891                 def_id.hash_stable(__hcx, __hasher);
892                 substs.hash_stable(__hcx, __hasher);
893                 m.hash_stable(__hcx, __hasher);
894             }
895             GeneratorWitness(b) => {
896                 b.hash_stable(__hcx, __hasher);
897             }
898             Never => {}
899             Tuple(substs) => {
900                 substs.hash_stable(__hcx, __hasher);
901             }
902             Projection(p) => {
903                 p.hash_stable(__hcx, __hasher);
904             }
905             Opaque(def_id, substs) => {
906                 def_id.hash_stable(__hcx, __hasher);
907                 substs.hash_stable(__hcx, __hasher);
908             }
909             Param(p) => {
910                 p.hash_stable(__hcx, __hasher);
911             }
912             Bound(d, b) => {
913                 d.hash_stable(__hcx, __hasher);
914                 b.hash_stable(__hcx, __hasher);
915             }
916             Placeholder(p) => {
917                 p.hash_stable(__hcx, __hasher);
918             }
919             Infer(i) => {
920                 i.hash_stable(__hcx, __hasher);
921             }
922             Error(d) => {
923                 d.hash_stable(__hcx, __hasher);
924             }
925         }
926     }
927 }
928
929 /// Representation of regions. Note that the NLL checker uses a distinct
930 /// representation of regions. For this reason, it internally replaces all the
931 /// regions with inference variables -- the index of the variable is then used
932 /// to index into internal NLL data structures. See `rustc_const_eval::borrow_check`
933 /// module for more information.
934 ///
935 /// Note: operations are on the wrapper `Region` type, which is interned,
936 /// rather than this type.
937 ///
938 /// ## The Region lattice within a given function
939 ///
940 /// In general, the region lattice looks like
941 ///
942 /// ```text
943 /// static ----------+-----...------+       (greatest)
944 /// |                |              |
945 /// early-bound and  |              |
946 /// free regions     |              |
947 /// |                |              |
948 /// |                |              |
949 /// empty(root)   placeholder(U1)   |
950 /// |            /                  |
951 /// |           /         placeholder(Un)
952 /// empty(U1) --         /
953 /// |                   /
954 /// ...                /
955 /// |                 /
956 /// empty(Un) --------                      (smallest)
957 /// ```
958 ///
959 /// Early-bound/free regions are the named lifetimes in scope from the
960 /// function declaration. They have relationships to one another
961 /// determined based on the declared relationships from the
962 /// function.
963 ///
964 /// Note that inference variables and bound regions are not included
965 /// in this diagram. In the case of inference variables, they should
966 /// be inferred to some other region from the diagram.  In the case of
967 /// bound regions, they are excluded because they don't make sense to
968 /// include -- the diagram indicates the relationship between free
969 /// regions.
970 ///
971 /// ## Inference variables
972 ///
973 /// During region inference, we sometimes create inference variables,
974 /// represented as `ReVar`. These will be inferred by the code in
975 /// `infer::lexical_region_resolve` to some free region from the
976 /// lattice above (the minimal region that meets the
977 /// constraints).
978 ///
979 /// During NLL checking, where regions are defined differently, we
980 /// also use `ReVar` -- in that case, the index is used to index into
981 /// the NLL region checker's data structures. The variable may in fact
982 /// represent either a free region or an inference variable, in that
983 /// case.
984 ///
985 /// ## Bound Regions
986 ///
987 /// These are regions that are stored behind a binder and must be substituted
988 /// with some concrete region before being used. There are two kind of
989 /// bound regions: early-bound, which are bound in an item's `Generics`,
990 /// and are substituted by an `InternalSubsts`, and late-bound, which are part of
991 /// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by
992 /// the likes of `liberate_late_bound_regions`. The distinction exists
993 /// because higher-ranked lifetimes aren't supported in all places. See [1][2].
994 ///
995 /// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
996 /// outside their binder, e.g., in types passed to type inference, and
997 /// should first be substituted (by placeholder regions, free regions,
998 /// or region variables).
999 ///
1000 /// ## Placeholder and Free Regions
1001 ///
1002 /// One often wants to work with bound regions without knowing their precise
1003 /// identity. For example, when checking a function, the lifetime of a borrow
1004 /// can end up being assigned to some region parameter. In these cases,
1005 /// it must be ensured that bounds on the region can't be accidentally
1006 /// assumed without being checked.
1007 ///
1008 /// To do this, we replace the bound regions with placeholder markers,
1009 /// which don't satisfy any relation not explicitly provided.
1010 ///
1011 /// There are two kinds of placeholder regions in rustc: `ReFree` and
1012 /// `RePlaceholder`. When checking an item's body, `ReFree` is supposed
1013 /// to be used. These also support explicit bounds: both the internally-stored
1014 /// *scope*, which the region is assumed to outlive, as well as other
1015 /// relations stored in the `FreeRegionMap`. Note that these relations
1016 /// aren't checked when you `make_subregion` (or `eq_types`), only by
1017 /// `resolve_regions_and_report_errors`.
1018 ///
1019 /// When working with higher-ranked types, some region relations aren't
1020 /// yet known, so you can't just call `resolve_regions_and_report_errors`.
1021 /// `RePlaceholder` is designed for this purpose. In these contexts,
1022 /// there's also the risk that some inference variable laying around will
1023 /// get unified with your placeholder region: if you want to check whether
1024 /// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
1025 /// with a placeholder region `'%a`, the variable `'_` would just be
1026 /// instantiated to the placeholder region `'%a`, which is wrong because
1027 /// the inference variable is supposed to satisfy the relation
1028 /// *for every value of the placeholder region*. To ensure that doesn't
1029 /// happen, you can use `leak_check`. This is more clearly explained
1030 /// by the [rustc dev guide].
1031 ///
1032 /// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
1033 /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
1034 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
1035 pub enum RegionKind<I: Interner> {
1036     /// Region bound in a type or fn declaration which will be
1037     /// substituted 'early' -- that is, at the same time when type
1038     /// parameters are substituted.
1039     ReEarlyBound(I::EarlyBoundRegion),
1040
1041     /// Region bound in a function scope, which will be substituted when the
1042     /// function is called.
1043     ReLateBound(DebruijnIndex, I::BoundRegion),
1044
1045     /// When checking a function body, the types of all arguments and so forth
1046     /// that refer to bound region parameters are modified to refer to free
1047     /// region parameters.
1048     ReFree(I::FreeRegion),
1049
1050     /// Static data that has an "infinite" lifetime. Top in the region lattice.
1051     ReStatic,
1052
1053     /// A region variable. Should not exist outside of type inference.
1054     ReVar(I::RegionVid),
1055
1056     /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
1057     /// Should not exist outside of type inference.
1058     RePlaceholder(I::PlaceholderRegion),
1059
1060     /// Erased region, used by trait selection, in MIR and during codegen.
1061     ReErased,
1062 }
1063
1064 // This is manually implemented for `RegionKind` because `std::mem::discriminant`
1065 // returns an opaque value that is `PartialEq` but not `PartialOrd`
1066 #[inline]
1067 const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
1068     match value {
1069         ReEarlyBound(_) => 0,
1070         ReLateBound(_, _) => 1,
1071         ReFree(_) => 2,
1072         ReStatic => 3,
1073         ReVar(_) => 4,
1074         RePlaceholder(_) => 5,
1075         ReErased => 6,
1076     }
1077 }
1078
1079 // This is manually implemented because a derive would require `I: Copy`
1080 impl<I: Interner> Copy for RegionKind<I>
1081 where
1082     I::EarlyBoundRegion: Copy,
1083     I::BoundRegion: Copy,
1084     I::FreeRegion: Copy,
1085     I::RegionVid: Copy,
1086     I::PlaceholderRegion: Copy,
1087 {
1088 }
1089
1090 // This is manually implemented because a derive would require `I: Clone`
1091 impl<I: Interner> Clone for RegionKind<I> {
1092     fn clone(&self) -> Self {
1093         match self {
1094             ReEarlyBound(a) => ReEarlyBound(a.clone()),
1095             ReLateBound(a, b) => ReLateBound(a.clone(), b.clone()),
1096             ReFree(a) => ReFree(a.clone()),
1097             ReStatic => ReStatic,
1098             ReVar(a) => ReVar(a.clone()),
1099             RePlaceholder(a) => RePlaceholder(a.clone()),
1100             ReErased => ReErased,
1101         }
1102     }
1103 }
1104
1105 // This is manually implemented because a derive would require `I: PartialEq`
1106 impl<I: Interner> PartialEq for RegionKind<I> {
1107     #[inline]
1108     fn eq(&self, other: &RegionKind<I>) -> bool {
1109         let __self_vi = regionkind_discriminant(self);
1110         let __arg_1_vi = regionkind_discriminant(other);
1111         if __self_vi == __arg_1_vi {
1112             match (&*self, &*other) {
1113                 (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
1114                     __self_0 == __arg_1_0
1115                 }
1116                 (
1117                     &ReLateBound(ref __self_0, ref __self_1),
1118                     &ReLateBound(ref __arg_1_0, ref __arg_1_1),
1119                 ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1,
1120                 (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => __self_0 == __arg_1_0,
1121                 (&ReStatic, &ReStatic) => true,
1122                 (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => __self_0 == __arg_1_0,
1123                 (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
1124                     __self_0 == __arg_1_0
1125                 }
1126                 (&ReErased, &ReErased) => true,
1127                 _ => true,
1128             }
1129         } else {
1130             false
1131         }
1132     }
1133 }
1134
1135 // This is manually implemented because a derive would require `I: Eq`
1136 impl<I: Interner> Eq for RegionKind<I> {}
1137
1138 // This is manually implemented because a derive would require `I: PartialOrd`
1139 impl<I: Interner> PartialOrd for RegionKind<I> {
1140     #[inline]
1141     fn partial_cmp(&self, other: &RegionKind<I>) -> Option<Ordering> {
1142         Some(Ord::cmp(self, other))
1143     }
1144 }
1145
1146 // This is manually implemented because a derive would require `I: Ord`
1147 impl<I: Interner> Ord for RegionKind<I> {
1148     #[inline]
1149     fn cmp(&self, other: &RegionKind<I>) -> Ordering {
1150         let __self_vi = regionkind_discriminant(self);
1151         let __arg_1_vi = regionkind_discriminant(other);
1152         if __self_vi == __arg_1_vi {
1153             match (&*self, &*other) {
1154                 (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
1155                     Ord::cmp(__self_0, __arg_1_0)
1156                 }
1157                 (
1158                     &ReLateBound(ref __self_0, ref __self_1),
1159                     &ReLateBound(ref __arg_1_0, ref __arg_1_1),
1160                 ) => match Ord::cmp(__self_0, __arg_1_0) {
1161                     Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
1162                     cmp => cmp,
1163                 },
1164                 (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
1165                 (&ReStatic, &ReStatic) => Ordering::Equal,
1166                 (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
1167                 (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
1168                     Ord::cmp(__self_0, __arg_1_0)
1169                 }
1170                 (&ReErased, &ReErased) => Ordering::Equal,
1171                 _ => Ordering::Equal,
1172             }
1173         } else {
1174             Ord::cmp(&__self_vi, &__arg_1_vi)
1175         }
1176     }
1177 }
1178
1179 // This is manually implemented because a derive would require `I: Hash`
1180 impl<I: Interner> hash::Hash for RegionKind<I> {
1181     fn hash<__H: hash::Hasher>(&self, state: &mut __H) -> () {
1182         match (&*self,) {
1183             (&ReEarlyBound(ref __self_0),) => {
1184                 hash::Hash::hash(&regionkind_discriminant(self), state);
1185                 hash::Hash::hash(__self_0, state)
1186             }
1187             (&ReLateBound(ref __self_0, ref __self_1),) => {
1188                 hash::Hash::hash(&regionkind_discriminant(self), state);
1189                 hash::Hash::hash(__self_0, state);
1190                 hash::Hash::hash(__self_1, state)
1191             }
1192             (&ReFree(ref __self_0),) => {
1193                 hash::Hash::hash(&regionkind_discriminant(self), state);
1194                 hash::Hash::hash(__self_0, state)
1195             }
1196             (&ReStatic,) => {
1197                 hash::Hash::hash(&regionkind_discriminant(self), state);
1198             }
1199             (&ReVar(ref __self_0),) => {
1200                 hash::Hash::hash(&regionkind_discriminant(self), state);
1201                 hash::Hash::hash(__self_0, state)
1202             }
1203             (&RePlaceholder(ref __self_0),) => {
1204                 hash::Hash::hash(&regionkind_discriminant(self), state);
1205                 hash::Hash::hash(__self_0, state)
1206             }
1207             (&ReErased,) => {
1208                 hash::Hash::hash(&regionkind_discriminant(self), state);
1209             }
1210         }
1211     }
1212 }
1213
1214 // This is manually implemented because a derive would require `I: Debug`
1215 impl<I: Interner> fmt::Debug for RegionKind<I> {
1216     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1217         match self {
1218             ReEarlyBound(ref data) => write!(f, "ReEarlyBound({:?})", data),
1219
1220             ReLateBound(binder_id, ref bound_region) => {
1221                 write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
1222             }
1223
1224             ReFree(ref fr) => fr.fmt(f),
1225
1226             ReStatic => write!(f, "ReStatic"),
1227
1228             ReVar(ref vid) => vid.fmt(f),
1229
1230             RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
1231
1232             ReErased => write!(f, "ReErased"),
1233         }
1234     }
1235 }
1236
1237 // This is manually implemented because a derive would require `I: Encodable`
1238 impl<I: Interner, E: TyEncoder> Encodable<E> for RegionKind<I>
1239 where
1240     I::EarlyBoundRegion: Encodable<E>,
1241     I::BoundRegion: Encodable<E>,
1242     I::FreeRegion: Encodable<E>,
1243     I::RegionVid: Encodable<E>,
1244     I::PlaceholderRegion: Encodable<E>,
1245 {
1246     fn encode(&self, e: &mut E) {
1247         let disc = regionkind_discriminant(self);
1248         match self {
1249             ReEarlyBound(a) => e.emit_enum_variant(disc, |e| {
1250                 a.encode(e);
1251             }),
1252             ReLateBound(a, b) => e.emit_enum_variant(disc, |e| {
1253                 a.encode(e);
1254                 b.encode(e);
1255             }),
1256             ReFree(a) => e.emit_enum_variant(disc, |e| {
1257                 a.encode(e);
1258             }),
1259             ReStatic => e.emit_enum_variant(disc, |_| {}),
1260             ReVar(a) => e.emit_enum_variant(disc, |e| {
1261                 a.encode(e);
1262             }),
1263             RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
1264                 a.encode(e);
1265             }),
1266             ReErased => e.emit_enum_variant(disc, |_| {}),
1267         }
1268     }
1269 }
1270
1271 // This is manually implemented because a derive would require `I: Decodable`
1272 impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for RegionKind<I>
1273 where
1274     I::EarlyBoundRegion: Decodable<D>,
1275     I::BoundRegion: Decodable<D>,
1276     I::FreeRegion: Decodable<D>,
1277     I::RegionVid: Decodable<D>,
1278     I::PlaceholderRegion: Decodable<D>,
1279 {
1280     fn decode(d: &mut D) -> Self {
1281         match Decoder::read_usize(d) {
1282             0 => ReEarlyBound(Decodable::decode(d)),
1283             1 => ReLateBound(Decodable::decode(d), Decodable::decode(d)),
1284             2 => ReFree(Decodable::decode(d)),
1285             3 => ReStatic,
1286             4 => ReVar(Decodable::decode(d)),
1287             5 => RePlaceholder(Decodable::decode(d)),
1288             6 => ReErased,
1289             _ => panic!(
1290                 "{}",
1291                 format!(
1292                     "invalid enum variant tag while decoding `{}`, expected 0..{}",
1293                     "RegionKind", 8,
1294                 )
1295             ),
1296         }
1297     }
1298 }
1299
1300 // This is not a derived impl because a derive would require `I: HashStable`
1301 impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for RegionKind<I>
1302 where
1303     I::EarlyBoundRegion: HashStable<CTX>,
1304     I::BoundRegion: HashStable<CTX>,
1305     I::FreeRegion: HashStable<CTX>,
1306     I::RegionVid: HashStable<CTX>,
1307     I::PlaceholderRegion: HashStable<CTX>,
1308 {
1309     #[inline]
1310     fn hash_stable(
1311         &self,
1312         hcx: &mut CTX,
1313         hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
1314     ) {
1315         std::mem::discriminant(self).hash_stable(hcx, hasher);
1316         match self {
1317             ReErased | ReStatic => {
1318                 // No variant fields to hash for these ...
1319             }
1320             ReLateBound(db, br) => {
1321                 db.hash_stable(hcx, hasher);
1322                 br.hash_stable(hcx, hasher);
1323             }
1324             ReEarlyBound(eb) => {
1325                 eb.hash_stable(hcx, hasher);
1326             }
1327             ReFree(ref free_region) => {
1328                 free_region.hash_stable(hcx, hasher);
1329             }
1330             RePlaceholder(p) => {
1331                 p.hash_stable(hcx, hasher);
1332             }
1333             ReVar(_) => {
1334                 panic!("region variables should not be hashed: {self:?}")
1335             }
1336         }
1337     }
1338 }