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::DelaySpanBugEmitted),
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::DelaySpanBugEmitted: 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::DelaySpanBugEmitted: Encodable<E>,
649 I::PredicateKind: Encodable<E>,
650 I::AllocId: Encodable<E>,
652 fn encode(&self, e: &mut E) {
653 let disc = tykind_discriminant(self);
655 Bool => e.emit_enum_variant(disc, |_| {}),
656 Char => e.emit_enum_variant(disc, |_| {}),
657 Int(i) => e.emit_enum_variant(disc, |e| {
660 Uint(u) => e.emit_enum_variant(disc, |e| {
663 Float(f) => e.emit_enum_variant(disc, |e| {
666 Adt(adt, substs) => e.emit_enum_variant(disc, |e| {
670 Foreign(def_id) => e.emit_enum_variant(disc, |e| {
673 Str => e.emit_enum_variant(disc, |_| {}),
674 Array(t, c) => e.emit_enum_variant(disc, |e| {
678 Slice(t) => e.emit_enum_variant(disc, |e| {
681 RawPtr(tam) => e.emit_enum_variant(disc, |e| {
684 Ref(r, t, m) => e.emit_enum_variant(disc, |e| {
689 FnDef(def_id, substs) => e.emit_enum_variant(disc, |e| {
693 FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| {
696 Dynamic(l, r, repr) => e.emit_enum_variant(disc, |e| {
701 Closure(def_id, substs) => e.emit_enum_variant(disc, |e| {
705 Generator(def_id, substs, m) => e.emit_enum_variant(disc, |e| {
710 GeneratorWitness(b) => e.emit_enum_variant(disc, |e| {
713 Never => e.emit_enum_variant(disc, |_| {}),
714 Tuple(substs) => e.emit_enum_variant(disc, |e| {
717 Projection(p) => e.emit_enum_variant(disc, |e| {
720 Opaque(def_id, substs) => e.emit_enum_variant(disc, |e| {
724 Param(p) => e.emit_enum_variant(disc, |e| {
727 Bound(d, b) => e.emit_enum_variant(disc, |e| {
731 Placeholder(p) => e.emit_enum_variant(disc, |e| {
734 Infer(i) => e.emit_enum_variant(disc, |e| {
737 Error(d) => e.emit_enum_variant(disc, |e| {
744 // This is manually implemented because a derive would require `I: Decodable`
745 impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for TyKind<I>
747 I::DelaySpanBugEmitted: Decodable<D>,
748 I::AdtDef: Decodable<D>,
749 I::SubstsRef: Decodable<D>,
750 I::DefId: Decodable<D>,
752 I::Const: Decodable<D>,
753 I::Region: Decodable<D>,
754 I::TypeAndMut: Decodable<D>,
755 I::Mutability: Decodable<D>,
756 I::Movability: Decodable<D>,
757 I::PolyFnSig: Decodable<D>,
758 I::ListBinderExistentialPredicate: Decodable<D>,
759 I::BinderListTy: Decodable<D>,
760 I::ListTy: Decodable<D>,
761 I::ProjectionTy: Decodable<D>,
762 I::ParamTy: Decodable<D>,
763 I::BoundTy: Decodable<D>,
764 I::PlaceholderType: Decodable<D>,
765 I::InferTy: Decodable<D>,
766 I::DelaySpanBugEmitted: Decodable<D>,
767 I::PredicateKind: Decodable<D>,
768 I::AllocId: Decodable<D>,
770 fn decode(d: &mut D) -> Self {
771 match Decoder::read_usize(d) {
774 2 => Int(Decodable::decode(d)),
775 3 => Uint(Decodable::decode(d)),
776 4 => Float(Decodable::decode(d)),
777 5 => Adt(Decodable::decode(d), Decodable::decode(d)),
778 6 => Foreign(Decodable::decode(d)),
780 8 => Array(Decodable::decode(d), Decodable::decode(d)),
781 9 => Slice(Decodable::decode(d)),
782 10 => RawPtr(Decodable::decode(d)),
783 11 => Ref(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
784 12 => FnDef(Decodable::decode(d), Decodable::decode(d)),
785 13 => FnPtr(Decodable::decode(d)),
786 14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
787 15 => Closure(Decodable::decode(d), Decodable::decode(d)),
788 16 => Generator(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
789 17 => GeneratorWitness(Decodable::decode(d)),
791 19 => Tuple(Decodable::decode(d)),
792 20 => Projection(Decodable::decode(d)),
793 21 => Opaque(Decodable::decode(d), Decodable::decode(d)),
794 22 => Param(Decodable::decode(d)),
795 23 => Bound(Decodable::decode(d), Decodable::decode(d)),
796 24 => Placeholder(Decodable::decode(d)),
797 25 => Infer(Decodable::decode(d)),
798 26 => Error(Decodable::decode(d)),
802 "invalid enum variant tag while decoding `{}`, expected 0..{}",
810 // This is not a derived impl because a derive would require `I: HashStable`
811 #[allow(rustc::usage_of_ty_tykind)]
812 impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for TyKind<I>
814 I::AdtDef: HashStable<CTX>,
815 I::DefId: HashStable<CTX>,
816 I::SubstsRef: HashStable<CTX>,
817 I::Ty: HashStable<CTX>,
818 I::Const: HashStable<CTX>,
819 I::TypeAndMut: HashStable<CTX>,
820 I::PolyFnSig: HashStable<CTX>,
821 I::ListBinderExistentialPredicate: HashStable<CTX>,
822 I::Region: HashStable<CTX>,
823 I::Movability: HashStable<CTX>,
824 I::Mutability: HashStable<CTX>,
825 I::BinderListTy: HashStable<CTX>,
826 I::ListTy: HashStable<CTX>,
827 I::ProjectionTy: HashStable<CTX>,
828 I::BoundTy: HashStable<CTX>,
829 I::ParamTy: HashStable<CTX>,
830 I::PlaceholderType: HashStable<CTX>,
831 I::InferTy: HashStable<CTX>,
832 I::DelaySpanBugEmitted: HashStable<CTX>,
838 __hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
840 std::mem::discriminant(self).hash_stable(__hcx, __hasher);
845 i.hash_stable(__hcx, __hasher);
848 u.hash_stable(__hcx, __hasher);
851 f.hash_stable(__hcx, __hasher);
853 Adt(adt, substs) => {
854 adt.hash_stable(__hcx, __hasher);
855 substs.hash_stable(__hcx, __hasher);
858 def_id.hash_stable(__hcx, __hasher);
862 t.hash_stable(__hcx, __hasher);
863 c.hash_stable(__hcx, __hasher);
866 t.hash_stable(__hcx, __hasher);
869 tam.hash_stable(__hcx, __hasher);
872 r.hash_stable(__hcx, __hasher);
873 t.hash_stable(__hcx, __hasher);
874 m.hash_stable(__hcx, __hasher);
876 FnDef(def_id, substs) => {
877 def_id.hash_stable(__hcx, __hasher);
878 substs.hash_stable(__hcx, __hasher);
880 FnPtr(polyfnsig) => {
881 polyfnsig.hash_stable(__hcx, __hasher);
883 Dynamic(l, r, repr) => {
884 l.hash_stable(__hcx, __hasher);
885 r.hash_stable(__hcx, __hasher);
886 repr.hash_stable(__hcx, __hasher);
888 Closure(def_id, substs) => {
889 def_id.hash_stable(__hcx, __hasher);
890 substs.hash_stable(__hcx, __hasher);
892 Generator(def_id, substs, m) => {
893 def_id.hash_stable(__hcx, __hasher);
894 substs.hash_stable(__hcx, __hasher);
895 m.hash_stable(__hcx, __hasher);
897 GeneratorWitness(b) => {
898 b.hash_stable(__hcx, __hasher);
902 substs.hash_stable(__hcx, __hasher);
905 p.hash_stable(__hcx, __hasher);
907 Opaque(def_id, substs) => {
908 def_id.hash_stable(__hcx, __hasher);
909 substs.hash_stable(__hcx, __hasher);
912 p.hash_stable(__hcx, __hasher);
915 d.hash_stable(__hcx, __hasher);
916 b.hash_stable(__hcx, __hasher);
919 p.hash_stable(__hcx, __hasher);
922 i.hash_stable(__hcx, __hasher);
925 d.hash_stable(__hcx, __hasher);
931 /// Representation of regions. Note that the NLL checker uses a distinct
932 /// representation of regions. For this reason, it internally replaces all the
933 /// regions with inference variables -- the index of the variable is then used
934 /// to index into internal NLL data structures. See `rustc_const_eval::borrow_check`
935 /// module for more information.
937 /// Note: operations are on the wrapper `Region` type, which is interned,
938 /// rather than this type.
940 /// ## The Region lattice within a given function
942 /// In general, the region lattice looks like
945 /// static ----------+-----...------+ (greatest)
947 /// early-bound and | |
951 /// empty(root) placeholder(U1) |
953 /// | / placeholder(Un)
958 /// empty(Un) -------- (smallest)
961 /// Early-bound/free regions are the named lifetimes in scope from the
962 /// function declaration. They have relationships to one another
963 /// determined based on the declared relationships from the
966 /// Note that inference variables and bound regions are not included
967 /// in this diagram. In the case of inference variables, they should
968 /// be inferred to some other region from the diagram. In the case of
969 /// bound regions, they are excluded because they don't make sense to
970 /// include -- the diagram indicates the relationship between free
973 /// ## Inference variables
975 /// During region inference, we sometimes create inference variables,
976 /// represented as `ReVar`. These will be inferred by the code in
977 /// `infer::lexical_region_resolve` to some free region from the
978 /// lattice above (the minimal region that meets the
981 /// During NLL checking, where regions are defined differently, we
982 /// also use `ReVar` -- in that case, the index is used to index into
983 /// the NLL region checker's data structures. The variable may in fact
984 /// represent either a free region or an inference variable, in that
989 /// These are regions that are stored behind a binder and must be substituted
990 /// with some concrete region before being used. There are two kind of
991 /// bound regions: early-bound, which are bound in an item's `Generics`,
992 /// and are substituted by an `InternalSubsts`, and late-bound, which are part of
993 /// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by
994 /// the likes of `liberate_late_bound_regions`. The distinction exists
995 /// because higher-ranked lifetimes aren't supported in all places. See [1][2].
997 /// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
998 /// outside their binder, e.g., in types passed to type inference, and
999 /// should first be substituted (by placeholder regions, free regions,
1000 /// or region variables).
1002 /// ## Placeholder and Free Regions
1004 /// One often wants to work with bound regions without knowing their precise
1005 /// identity. For example, when checking a function, the lifetime of a borrow
1006 /// can end up being assigned to some region parameter. In these cases,
1007 /// it must be ensured that bounds on the region can't be accidentally
1008 /// assumed without being checked.
1010 /// To do this, we replace the bound regions with placeholder markers,
1011 /// which don't satisfy any relation not explicitly provided.
1013 /// There are two kinds of placeholder regions in rustc: `ReFree` and
1014 /// `RePlaceholder`. When checking an item's body, `ReFree` is supposed
1015 /// to be used. These also support explicit bounds: both the internally-stored
1016 /// *scope*, which the region is assumed to outlive, as well as other
1017 /// relations stored in the `FreeRegionMap`. Note that these relations
1018 /// aren't checked when you `make_subregion` (or `eq_types`), only by
1019 /// `resolve_regions_and_report_errors`.
1021 /// When working with higher-ranked types, some region relations aren't
1022 /// yet known, so you can't just call `resolve_regions_and_report_errors`.
1023 /// `RePlaceholder` is designed for this purpose. In these contexts,
1024 /// there's also the risk that some inference variable laying around will
1025 /// get unified with your placeholder region: if you want to check whether
1026 /// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
1027 /// with a placeholder region `'%a`, the variable `'_` would just be
1028 /// instantiated to the placeholder region `'%a`, which is wrong because
1029 /// the inference variable is supposed to satisfy the relation
1030 /// *for every value of the placeholder region*. To ensure that doesn't
1031 /// happen, you can use `leak_check`. This is more clearly explained
1032 /// by the [rustc dev guide].
1034 /// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
1035 /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
1036 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
1037 pub enum RegionKind<I: Interner> {
1038 /// Region bound in a type or fn declaration which will be
1039 /// substituted 'early' -- that is, at the same time when type
1040 /// parameters are substituted.
1041 ReEarlyBound(I::EarlyBoundRegion),
1043 /// Region bound in a function scope, which will be substituted when the
1044 /// function is called.
1045 ReLateBound(DebruijnIndex, I::BoundRegion),
1047 /// When checking a function body, the types of all arguments and so forth
1048 /// that refer to bound region parameters are modified to refer to free
1049 /// region parameters.
1050 ReFree(I::FreeRegion),
1052 /// Static data that has an "infinite" lifetime. Top in the region lattice.
1055 /// A region variable. Should not exist outside of type inference.
1056 ReVar(I::RegionVid),
1058 /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
1059 /// Should not exist outside of type inference.
1060 RePlaceholder(I::PlaceholderRegion),
1062 /// Erased region, used by trait selection, in MIR and during codegen.
1066 // This is manually implemented for `RegionKind` because `std::mem::discriminant`
1067 // returns an opaque value that is `PartialEq` but not `PartialOrd`
1069 const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
1071 ReEarlyBound(_) => 0,
1072 ReLateBound(_, _) => 1,
1076 RePlaceholder(_) => 5,
1081 // This is manually implemented because a derive would require `I: Copy`
1082 impl<I: Interner> Copy for RegionKind<I>
1084 I::EarlyBoundRegion: Copy,
1085 I::BoundRegion: Copy,
1086 I::FreeRegion: Copy,
1088 I::PlaceholderRegion: Copy,
1092 // This is manually implemented because a derive would require `I: Clone`
1093 impl<I: Interner> Clone for RegionKind<I> {
1094 fn clone(&self) -> Self {
1096 ReEarlyBound(a) => ReEarlyBound(a.clone()),
1097 ReLateBound(a, b) => ReLateBound(a.clone(), b.clone()),
1098 ReFree(a) => ReFree(a.clone()),
1099 ReStatic => ReStatic,
1100 ReVar(a) => ReVar(a.clone()),
1101 RePlaceholder(a) => RePlaceholder(a.clone()),
1102 ReErased => ReErased,
1107 // This is manually implemented because a derive would require `I: PartialEq`
1108 impl<I: Interner> PartialEq for RegionKind<I> {
1110 fn eq(&self, other: &RegionKind<I>) -> bool {
1111 let __self_vi = regionkind_discriminant(self);
1112 let __arg_1_vi = regionkind_discriminant(other);
1113 if __self_vi == __arg_1_vi {
1114 match (&*self, &*other) {
1115 (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
1116 __self_0 == __arg_1_0
1119 &ReLateBound(ref __self_0, ref __self_1),
1120 &ReLateBound(ref __arg_1_0, ref __arg_1_1),
1121 ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1,
1122 (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => __self_0 == __arg_1_0,
1123 (&ReStatic, &ReStatic) => true,
1124 (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => __self_0 == __arg_1_0,
1125 (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
1126 __self_0 == __arg_1_0
1128 (&ReErased, &ReErased) => true,
1137 // This is manually implemented because a derive would require `I: Eq`
1138 impl<I: Interner> Eq for RegionKind<I> {}
1140 // This is manually implemented because a derive would require `I: PartialOrd`
1141 impl<I: Interner> PartialOrd for RegionKind<I> {
1143 fn partial_cmp(&self, other: &RegionKind<I>) -> Option<Ordering> {
1144 Some(Ord::cmp(self, other))
1148 // This is manually implemented because a derive would require `I: Ord`
1149 impl<I: Interner> Ord for RegionKind<I> {
1151 fn cmp(&self, other: &RegionKind<I>) -> Ordering {
1152 let __self_vi = regionkind_discriminant(self);
1153 let __arg_1_vi = regionkind_discriminant(other);
1154 if __self_vi == __arg_1_vi {
1155 match (&*self, &*other) {
1156 (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
1157 Ord::cmp(__self_0, __arg_1_0)
1160 &ReLateBound(ref __self_0, ref __self_1),
1161 &ReLateBound(ref __arg_1_0, ref __arg_1_1),
1162 ) => match Ord::cmp(__self_0, __arg_1_0) {
1163 Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
1166 (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
1167 (&ReStatic, &ReStatic) => Ordering::Equal,
1168 (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
1169 (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
1170 Ord::cmp(__self_0, __arg_1_0)
1172 (&ReErased, &ReErased) => Ordering::Equal,
1173 _ => Ordering::Equal,
1176 Ord::cmp(&__self_vi, &__arg_1_vi)
1181 // This is manually implemented because a derive would require `I: Hash`
1182 impl<I: Interner> hash::Hash for RegionKind<I> {
1183 fn hash<__H: hash::Hasher>(&self, state: &mut __H) -> () {
1185 (&ReEarlyBound(ref __self_0),) => {
1186 hash::Hash::hash(®ionkind_discriminant(self), state);
1187 hash::Hash::hash(__self_0, state)
1189 (&ReLateBound(ref __self_0, ref __self_1),) => {
1190 hash::Hash::hash(®ionkind_discriminant(self), state);
1191 hash::Hash::hash(__self_0, state);
1192 hash::Hash::hash(__self_1, state)
1194 (&ReFree(ref __self_0),) => {
1195 hash::Hash::hash(®ionkind_discriminant(self), state);
1196 hash::Hash::hash(__self_0, state)
1199 hash::Hash::hash(®ionkind_discriminant(self), state);
1201 (&ReVar(ref __self_0),) => {
1202 hash::Hash::hash(®ionkind_discriminant(self), state);
1203 hash::Hash::hash(__self_0, state)
1205 (&RePlaceholder(ref __self_0),) => {
1206 hash::Hash::hash(®ionkind_discriminant(self), state);
1207 hash::Hash::hash(__self_0, state)
1210 hash::Hash::hash(®ionkind_discriminant(self), state);
1216 // This is manually implemented because a derive would require `I: Debug`
1217 impl<I: Interner> fmt::Debug for RegionKind<I> {
1218 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1220 ReEarlyBound(ref data) => write!(f, "ReEarlyBound({:?})", data),
1222 ReLateBound(binder_id, ref bound_region) => {
1223 write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
1226 ReFree(ref fr) => fr.fmt(f),
1228 ReStatic => write!(f, "ReStatic"),
1230 ReVar(ref vid) => vid.fmt(f),
1232 RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
1234 ReErased => write!(f, "ReErased"),
1239 // This is manually implemented because a derive would require `I: Encodable`
1240 impl<I: Interner, E: TyEncoder> Encodable<E> for RegionKind<I>
1242 I::EarlyBoundRegion: Encodable<E>,
1243 I::BoundRegion: Encodable<E>,
1244 I::FreeRegion: Encodable<E>,
1245 I::RegionVid: Encodable<E>,
1246 I::PlaceholderRegion: Encodable<E>,
1248 fn encode(&self, e: &mut E) {
1249 let disc = regionkind_discriminant(self);
1251 ReEarlyBound(a) => e.emit_enum_variant(disc, |e| {
1254 ReLateBound(a, b) => e.emit_enum_variant(disc, |e| {
1258 ReFree(a) => e.emit_enum_variant(disc, |e| {
1261 ReStatic => e.emit_enum_variant(disc, |_| {}),
1262 ReVar(a) => e.emit_enum_variant(disc, |e| {
1265 RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
1268 ReErased => e.emit_enum_variant(disc, |_| {}),
1273 // This is manually implemented because a derive would require `I: Decodable`
1274 impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for RegionKind<I>
1276 I::EarlyBoundRegion: Decodable<D>,
1277 I::BoundRegion: Decodable<D>,
1278 I::FreeRegion: Decodable<D>,
1279 I::RegionVid: Decodable<D>,
1280 I::PlaceholderRegion: Decodable<D>,
1282 fn decode(d: &mut D) -> Self {
1283 match Decoder::read_usize(d) {
1284 0 => ReEarlyBound(Decodable::decode(d)),
1285 1 => ReLateBound(Decodable::decode(d), Decodable::decode(d)),
1286 2 => ReFree(Decodable::decode(d)),
1288 4 => ReVar(Decodable::decode(d)),
1289 5 => RePlaceholder(Decodable::decode(d)),
1294 "invalid enum variant tag while decoding `{}`, expected 0..{}",
1302 // This is not a derived impl because a derive would require `I: HashStable`
1303 impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for RegionKind<I>
1305 I::EarlyBoundRegion: HashStable<CTX>,
1306 I::BoundRegion: HashStable<CTX>,
1307 I::FreeRegion: HashStable<CTX>,
1308 I::RegionVid: HashStable<CTX>,
1309 I::PlaceholderRegion: HashStable<CTX>,
1315 hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
1317 std::mem::discriminant(self).hash_stable(hcx, hasher);
1319 ReErased | ReStatic => {
1320 // No variant fields to hash for these ...
1322 ReLateBound(db, br) => {
1323 db.hash_stable(hcx, hasher);
1324 br.hash_stable(hcx, hasher);
1326 ReEarlyBound(eb) => {
1327 eb.hash_stable(hcx, hasher);
1329 ReFree(ref free_region) => {
1330 free_region.hash_stable(hcx, hasher);
1332 RePlaceholder(p) => {
1333 p.hash_stable(hcx, hasher);
1336 panic!("region variables should not be hashed: {self:?}")