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