1 #![allow(rustc::usage_of_ty_tykind)]
3 use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
6 use crate::DebruijnIndex;
8 use crate::HashStableContext;
15 use self::RegionKind::*;
18 use rustc_data_structures::stable_hasher::HashStable;
19 use rustc_serialize::{Decodable, Decoder, Encodable};
21 /// Specifies how a trait object is represented.
36 /// An unsized `dyn Trait` object
38 /// A sized `dyn* Trait` object
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.
49 /// Defines the kinds of types used by the type system.
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`.
58 /// The primitive character type; holds a Unicode scalar value
59 /// (a non-surrogate code point). Written as `char`.
62 /// A primitive signed integer type. For example, `i32`.
65 /// A primitive unsigned integer type. For example, `u32`.
68 /// A primitive floating-point type. For example, `f64`.
71 /// Algebraic data types (ADT). For example: structures, enumerations and unions.
73 /// For example, the type `List<i32>` would be represented using the `AdtDef`
74 /// for `struct List<T>` and the substs `[i32]`.
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),
80 /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
83 /// The pointee of a string slice. Written as `str`.
86 /// An array with the given length. Written as `[T; N]`.
87 Array(I::Ty, I::Const),
89 /// The pointee of an array slice. Written as `[T]`.
92 /// A raw pointer. Written as `*mut T` or `*const T`
93 RawPtr(I::TypeAndMut),
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),
99 /// The anonymous type of a function declaration/definition. Each
100 /// function has a unique type.
102 /// For the function `fn foo() -> i32 { 3 }` this type would be
103 /// shown to the user as `fn() -> i32 {foo}`.
105 /// For example the type of `bar` here:
107 /// fn foo() -> i32 { 1 }
108 /// let bar = foo; // bar: fn() -> i32 {foo}
110 FnDef(I::DefId, I::SubstsRef),
112 /// A pointer to a function. Written as `fn() -> i32`.
114 /// Note that both functions and closures start out as either
115 /// [FnDef] or [Closure] which can be then be coerced to this variant.
117 /// For example the type of `bar` here:
120 /// fn foo() -> i32 { 1 }
121 /// let bar: fn() -> i32 = foo;
125 /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
126 Dynamic(I::ListBinderExistentialPredicate, I::Region, DynKind),
128 /// The anonymous type of a closure. Used to represent the type of `|a| a`.
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),
135 /// The anonymous type of a generator. Used to represent the type of
138 /// For more info about generator substs, visit the documentation for
139 /// `GeneratorSubsts`.
140 Generator(I::DefId, I::SubstsRef, I::Movability),
142 /// A type representing the types stored inside a generator.
143 /// This should only appear as part of the `GeneratorSubsts`.
145 /// Note that the captured variables for generators are stored separately
146 /// using a tuple in the same way as for closures.
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.
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>]`:
156 /// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?)
157 /// #![feature(generators)]
159 /// let x = &vec![3];
165 GeneratorWitness(I::BinderListTy),
167 /// The never type `!`.
170 /// A tuple type. For example, `(i32, bool)`.
173 /// The projection of an associated type. For example,
174 /// `<T as Trait<..>>::N`.
175 Projection(I::ProjectionTy),
177 /// Opaque (`impl Trait`) type found in a return type.
179 /// The `DefId` comes either from
180 /// * the `impl Trait` ast::Ty node,
181 /// * or the `type Foo = impl Trait` declaration
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.
186 /// During codegen, `tcx.type_of(def_id)` can be used to get the underlying type.
187 Opaque(I::DefId, I::SubstsRef),
189 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
192 /// Bound type variable, used to represent the `'a` in `for<'a> fn(&'a ())`.
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.
199 /// See the `rustc-dev-guide` for more details about
200 /// [higher-ranked trait bounds][1] and [canonical queries][2].
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),
206 /// A placeholder type, used during higher ranked subtyping to instantiate
208 Placeholder(I::PlaceholderType),
210 /// A type variable used during type checking.
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.
218 /// A placeholder for a type which could not be computed; this is
219 /// propagated to avoid useless error messages.
220 Error(I::ErrorGuaranteed),
223 impl<I: Interner> TyKind<I> {
225 pub fn is_primitive(&self) -> bool {
226 matches!(self, Bool | Char | Int(_) | Uint(_) | Float(_))
230 // This is manually implemented for `TyKind` because `std::mem::discriminant`
231 // returns an opaque value that is `PartialEq` but not `PartialOrd`
233 const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
251 Generator(_, _, _) => 16,
252 GeneratorWitness(_) => 17,
259 Placeholder(_) => 24,
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 {
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()),
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()),
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()),
300 // This is manually implemented because a derive would require `I: PartialEq`
301 impl<I: Interner> PartialEq for TyKind<I> {
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
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
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,
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
327 (&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => __self_0 == __arg_1_0,
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
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
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
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
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,
362 // This is manually implemented because a derive would require `I: Eq`
363 impl<I: Interner> Eq for TyKind<I> {}
365 // This is manually implemented because a derive would require `I: PartialOrd`
366 impl<I: Interner> PartialOrd for TyKind<I> {
368 fn partial_cmp(&self, other: &TyKind<I>) -> Option<Ordering> {
369 Some(Ord::cmp(self, other))
373 // This is manually implemented because a derive would require `I: Ord`
374 impl<I: Interner> Ord for TyKind<I> {
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),
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),
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),
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),
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),
415 (&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
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),
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),
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),
442 (&GeneratorWitness(ref __self_0), &GeneratorWitness(ref __arg_1_0)) => {
443 Ord::cmp(__self_0, __arg_1_0)
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)
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),
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),
462 (&Placeholder(ref __self_0), &Placeholder(ref __arg_1_0)) => {
463 Ord::cmp(__self_0, __arg_1_0)
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,
470 Ord::cmp(&__self_vi, &__arg_1_vi)
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) -> () {
479 (&Int(ref __self_0),) => {
480 hash::Hash::hash(&tykind_discriminant(self), state);
481 hash::Hash::hash(__self_0, state)
483 (&Uint(ref __self_0),) => {
484 hash::Hash::hash(&tykind_discriminant(self), state);
485 hash::Hash::hash(__self_0, state)
487 (&Float(ref __self_0),) => {
488 hash::Hash::hash(&tykind_discriminant(self), state);
489 hash::Hash::hash(__self_0, state)
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)
496 (&Foreign(ref __self_0),) => {
497 hash::Hash::hash(&tykind_discriminant(self), state);
498 hash::Hash::hash(__self_0, state)
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)
505 (&Slice(ref __self_0),) => {
506 hash::Hash::hash(&tykind_discriminant(self), state);
507 hash::Hash::hash(__self_0, state)
509 (&RawPtr(ref __self_0),) => {
510 hash::Hash::hash(&tykind_discriminant(self), state);
511 hash::Hash::hash(__self_0, state)
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)
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)
524 (&FnPtr(ref __self_0),) => {
525 hash::Hash::hash(&tykind_discriminant(self), state);
526 hash::Hash::hash(__self_0, state)
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)
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)
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)
545 (&GeneratorWitness(ref __self_0),) => {
546 hash::Hash::hash(&tykind_discriminant(self), state);
547 hash::Hash::hash(__self_0, state)
549 (&Tuple(ref __self_0),) => {
550 hash::Hash::hash(&tykind_discriminant(self), state);
551 hash::Hash::hash(__self_0, state)
553 (&Projection(ref __self_0),) => {
554 hash::Hash::hash(&tykind_discriminant(self), state);
555 hash::Hash::hash(__self_0, state)
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)
562 (&Param(ref __self_0),) => {
563 hash::Hash::hash(&tykind_discriminant(self), state);
564 hash::Hash::hash(__self_0, state)
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)
571 (&Placeholder(ref __self_0),) => {
572 hash::Hash::hash(&tykind_discriminant(self), state);
573 hash::Hash::hash(__self_0, state)
575 (&Infer(ref __self_0),) => {
576 hash::Hash::hash(&tykind_discriminant(self), state);
577 hash::Hash::hash(__self_0, state)
579 (&Error(ref __self_0),) => {
580 hash::Hash::hash(&tykind_discriminant(self), state);
581 hash::Hash::hash(__self_0, state)
583 _ => hash::Hash::hash(&tykind_discriminant(self), state),
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 {
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)
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),
626 // This is manually implemented because a derive would require `I: Encodable`
627 impl<I: Interner, E: TyEncoder> Encodable<E> for TyKind<I>
629 I::ErrorGuaranteed: Encodable<E>,
630 I::AdtDef: Encodable<E>,
631 I::SubstsRef: Encodable<E>,
632 I::DefId: 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>,
651 fn encode(&self, e: &mut E) {
652 let disc = tykind_discriminant(self);
654 Bool => e.emit_enum_variant(disc, |_| {}),
655 Char => e.emit_enum_variant(disc, |_| {}),
656 Int(i) => e.emit_enum_variant(disc, |e| {
659 Uint(u) => e.emit_enum_variant(disc, |e| {
662 Float(f) => e.emit_enum_variant(disc, |e| {
665 Adt(adt, substs) => e.emit_enum_variant(disc, |e| {
669 Foreign(def_id) => e.emit_enum_variant(disc, |e| {
672 Str => e.emit_enum_variant(disc, |_| {}),
673 Array(t, c) => e.emit_enum_variant(disc, |e| {
677 Slice(t) => e.emit_enum_variant(disc, |e| {
680 RawPtr(tam) => e.emit_enum_variant(disc, |e| {
683 Ref(r, t, m) => e.emit_enum_variant(disc, |e| {
688 FnDef(def_id, substs) => e.emit_enum_variant(disc, |e| {
692 FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| {
695 Dynamic(l, r, repr) => e.emit_enum_variant(disc, |e| {
700 Closure(def_id, substs) => e.emit_enum_variant(disc, |e| {
704 Generator(def_id, substs, m) => e.emit_enum_variant(disc, |e| {
709 GeneratorWitness(b) => e.emit_enum_variant(disc, |e| {
712 Never => e.emit_enum_variant(disc, |_| {}),
713 Tuple(substs) => e.emit_enum_variant(disc, |e| {
716 Projection(p) => e.emit_enum_variant(disc, |e| {
719 Opaque(def_id, substs) => e.emit_enum_variant(disc, |e| {
723 Param(p) => e.emit_enum_variant(disc, |e| {
726 Bound(d, b) => e.emit_enum_variant(disc, |e| {
730 Placeholder(p) => e.emit_enum_variant(disc, |e| {
733 Infer(i) => e.emit_enum_variant(disc, |e| {
736 Error(d) => e.emit_enum_variant(disc, |e| {
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>
746 I::ErrorGuaranteed: Decodable<D>,
747 I::AdtDef: Decodable<D>,
748 I::SubstsRef: Decodable<D>,
749 I::DefId: 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>,
768 fn decode(d: &mut D) -> Self {
769 match Decoder::read_usize(d) {
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)),
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)),
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)),
800 "invalid enum variant tag while decoding `{}`, expected 0..{}",
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>
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>,
836 __hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
838 std::mem::discriminant(self).hash_stable(__hcx, __hasher);
843 i.hash_stable(__hcx, __hasher);
846 u.hash_stable(__hcx, __hasher);
849 f.hash_stable(__hcx, __hasher);
851 Adt(adt, substs) => {
852 adt.hash_stable(__hcx, __hasher);
853 substs.hash_stable(__hcx, __hasher);
856 def_id.hash_stable(__hcx, __hasher);
860 t.hash_stable(__hcx, __hasher);
861 c.hash_stable(__hcx, __hasher);
864 t.hash_stable(__hcx, __hasher);
867 tam.hash_stable(__hcx, __hasher);
870 r.hash_stable(__hcx, __hasher);
871 t.hash_stable(__hcx, __hasher);
872 m.hash_stable(__hcx, __hasher);
874 FnDef(def_id, substs) => {
875 def_id.hash_stable(__hcx, __hasher);
876 substs.hash_stable(__hcx, __hasher);
878 FnPtr(polyfnsig) => {
879 polyfnsig.hash_stable(__hcx, __hasher);
881 Dynamic(l, r, repr) => {
882 l.hash_stable(__hcx, __hasher);
883 r.hash_stable(__hcx, __hasher);
884 repr.hash_stable(__hcx, __hasher);
886 Closure(def_id, substs) => {
887 def_id.hash_stable(__hcx, __hasher);
888 substs.hash_stable(__hcx, __hasher);
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);
895 GeneratorWitness(b) => {
896 b.hash_stable(__hcx, __hasher);
900 substs.hash_stable(__hcx, __hasher);
903 p.hash_stable(__hcx, __hasher);
905 Opaque(def_id, substs) => {
906 def_id.hash_stable(__hcx, __hasher);
907 substs.hash_stable(__hcx, __hasher);
910 p.hash_stable(__hcx, __hasher);
913 d.hash_stable(__hcx, __hasher);
914 b.hash_stable(__hcx, __hasher);
917 p.hash_stable(__hcx, __hasher);
920 i.hash_stable(__hcx, __hasher);
923 d.hash_stable(__hcx, __hasher);
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.
935 /// Note: operations are on the wrapper `Region` type, which is interned,
936 /// rather than this type.
938 /// ## The Region lattice within a given function
940 /// In general, the region lattice looks like
943 /// static ----------+-----...------+ (greatest)
945 /// early-bound and | |
949 /// empty(root) placeholder(U1) |
951 /// | / placeholder(Un)
956 /// empty(Un) -------- (smallest)
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
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
971 /// ## Inference variables
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
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
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].
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).
1000 /// ## Placeholder and Free Regions
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.
1008 /// To do this, we replace the bound regions with placeholder markers,
1009 /// which don't satisfy any relation not explicitly provided.
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`.
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].
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),
1041 /// Region bound in a function scope, which will be substituted when the
1042 /// function is called.
1043 ReLateBound(DebruijnIndex, I::BoundRegion),
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),
1050 /// Static data that has an "infinite" lifetime. Top in the region lattice.
1053 /// A region variable. Should not exist outside of type inference.
1054 ReVar(I::RegionVid),
1056 /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
1057 /// Should not exist outside of type inference.
1058 RePlaceholder(I::PlaceholderRegion),
1060 /// Erased region, used by trait selection, in MIR and during codegen.
1064 // This is manually implemented for `RegionKind` because `std::mem::discriminant`
1065 // returns an opaque value that is `PartialEq` but not `PartialOrd`
1067 const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
1069 ReEarlyBound(_) => 0,
1070 ReLateBound(_, _) => 1,
1074 RePlaceholder(_) => 5,
1079 // This is manually implemented because a derive would require `I: Copy`
1080 impl<I: Interner> Copy for RegionKind<I>
1082 I::EarlyBoundRegion: Copy,
1083 I::BoundRegion: Copy,
1084 I::FreeRegion: Copy,
1086 I::PlaceholderRegion: Copy,
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 {
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,
1105 // This is manually implemented because a derive would require `I: PartialEq`
1106 impl<I: Interner> PartialEq for RegionKind<I> {
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
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
1126 (&ReErased, &ReErased) => true,
1135 // This is manually implemented because a derive would require `I: Eq`
1136 impl<I: Interner> Eq for RegionKind<I> {}
1138 // This is manually implemented because a derive would require `I: PartialOrd`
1139 impl<I: Interner> PartialOrd for RegionKind<I> {
1141 fn partial_cmp(&self, other: &RegionKind<I>) -> Option<Ordering> {
1142 Some(Ord::cmp(self, other))
1146 // This is manually implemented because a derive would require `I: Ord`
1147 impl<I: Interner> Ord for RegionKind<I> {
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)
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),
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)
1170 (&ReErased, &ReErased) => Ordering::Equal,
1171 _ => Ordering::Equal,
1174 Ord::cmp(&__self_vi, &__arg_1_vi)
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) -> () {
1183 (&ReEarlyBound(ref __self_0),) => {
1184 hash::Hash::hash(®ionkind_discriminant(self), state);
1185 hash::Hash::hash(__self_0, state)
1187 (&ReLateBound(ref __self_0, ref __self_1),) => {
1188 hash::Hash::hash(®ionkind_discriminant(self), state);
1189 hash::Hash::hash(__self_0, state);
1190 hash::Hash::hash(__self_1, state)
1192 (&ReFree(ref __self_0),) => {
1193 hash::Hash::hash(®ionkind_discriminant(self), state);
1194 hash::Hash::hash(__self_0, state)
1197 hash::Hash::hash(®ionkind_discriminant(self), state);
1199 (&ReVar(ref __self_0),) => {
1200 hash::Hash::hash(®ionkind_discriminant(self), state);
1201 hash::Hash::hash(__self_0, state)
1203 (&RePlaceholder(ref __self_0),) => {
1204 hash::Hash::hash(®ionkind_discriminant(self), state);
1205 hash::Hash::hash(__self_0, state)
1208 hash::Hash::hash(®ionkind_discriminant(self), state);
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 {
1218 ReEarlyBound(ref data) => write!(f, "ReEarlyBound({:?})", data),
1220 ReLateBound(binder_id, ref bound_region) => {
1221 write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
1224 ReFree(ref fr) => fr.fmt(f),
1226 ReStatic => write!(f, "ReStatic"),
1228 ReVar(ref vid) => vid.fmt(f),
1230 RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
1232 ReErased => write!(f, "ReErased"),
1237 // This is manually implemented because a derive would require `I: Encodable`
1238 impl<I: Interner, E: TyEncoder> Encodable<E> for RegionKind<I>
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>,
1246 fn encode(&self, e: &mut E) {
1247 let disc = regionkind_discriminant(self);
1249 ReEarlyBound(a) => e.emit_enum_variant(disc, |e| {
1252 ReLateBound(a, b) => e.emit_enum_variant(disc, |e| {
1256 ReFree(a) => e.emit_enum_variant(disc, |e| {
1259 ReStatic => e.emit_enum_variant(disc, |_| {}),
1260 ReVar(a) => e.emit_enum_variant(disc, |e| {
1263 RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
1266 ReErased => e.emit_enum_variant(disc, |_| {}),
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>
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>,
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)),
1286 4 => ReVar(Decodable::decode(d)),
1287 5 => RePlaceholder(Decodable::decode(d)),
1292 "invalid enum variant tag while decoding `{}`, expected 0..{}",
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>
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>,
1313 hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
1315 std::mem::discriminant(self).hash_stable(hcx, hasher);
1317 ReErased | ReStatic => {
1318 // No variant fields to hash for these ...
1320 ReLateBound(db, br) => {
1321 db.hash_stable(hcx, hasher);
1322 br.hash_stable(hcx, hasher);
1324 ReEarlyBound(eb) => {
1325 eb.hash_stable(hcx, hasher);
1327 ReFree(ref free_region) => {
1328 free_region.hash_stable(hcx, hasher);
1330 RePlaceholder(p) => {
1331 p.hash_stable(hcx, hasher);
1334 panic!("region variables should not be hashed: {self:?}")