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.
22 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
23 pub enum TraitObjectRepresentation {
24 /// An unsized `dyn Trait` object
26 /// A sized `dyn* Trait` object
30 // Manually implemented because deriving HashStable requires rustc_query_system, which would
31 // create a cyclic dependency.
32 impl<CTX> HashStable<CTX> for TraitObjectRepresentation {
36 hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
38 std::mem::discriminant(self).hash_stable(hcx, hasher);
42 /// Defines the kinds of types used by the type system.
44 /// Types written by the user start out as `hir::TyKind` and get
45 /// converted to this representation using `AstConv::ast_ty_to_ty`.
46 #[rustc_diagnostic_item = "IrTyKind"]
47 pub enum TyKind<I: Interner> {
48 /// The primitive boolean type. Written as `bool`.
51 /// The primitive character type; holds a Unicode scalar value
52 /// (a non-surrogate code point). Written as `char`.
55 /// A primitive signed integer type. For example, `i32`.
58 /// A primitive unsigned integer type. For example, `u32`.
61 /// A primitive floating-point type. For example, `f64`.
64 /// Algebraic data types (ADT). For example: structures, enumerations and unions.
66 /// For example, the type `List<i32>` would be represented using the `AdtDef`
67 /// for `struct List<T>` and the substs `[i32]`.
69 /// Note that generic parameters in fields only get lazily substituted
70 /// by using something like `adt_def.all_fields().map(|field| field.ty(tcx, substs))`.
71 Adt(I::AdtDef, I::SubstsRef),
73 /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
76 /// The pointee of a string slice. Written as `str`.
79 /// An array with the given length. Written as `[T; N]`.
80 Array(I::Ty, I::Const),
82 /// The pointee of an array slice. Written as `[T]`.
85 /// A raw pointer. Written as `*mut T` or `*const T`
86 RawPtr(I::TypeAndMut),
88 /// A reference; a pointer with an associated lifetime. Written as
89 /// `&'a mut T` or `&'a T`.
90 Ref(I::Region, I::Ty, I::Mutability),
92 /// The anonymous type of a function declaration/definition. Each
93 /// function has a unique type.
95 /// For the function `fn foo() -> i32 { 3 }` this type would be
96 /// shown to the user as `fn() -> i32 {foo}`.
98 /// For example the type of `bar` here:
100 /// fn foo() -> i32 { 1 }
101 /// let bar = foo; // bar: fn() -> i32 {foo}
103 FnDef(I::DefId, I::SubstsRef),
105 /// A pointer to a function. Written as `fn() -> i32`.
107 /// Note that both functions and closures start out as either
108 /// [FnDef] or [Closure] which can be then be coerced to this variant.
110 /// For example the type of `bar` here:
113 /// fn foo() -> i32 { 1 }
114 /// let bar: fn() -> i32 = foo;
118 /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
119 Dynamic(I::ListBinderExistentialPredicate, I::Region, TraitObjectRepresentation),
121 /// The anonymous type of a closure. Used to represent the type of `|a| a`.
123 /// Closure substs contain both the - potentially substituted - generic parameters
124 /// of its parent and some synthetic parameters. See the documentation for
125 /// `ClosureSubsts` for more details.
126 Closure(I::DefId, I::SubstsRef),
128 /// The anonymous type of a generator. Used to represent the type of
131 /// For more info about generator substs, visit the documentation for
132 /// `GeneratorSubsts`.
133 Generator(I::DefId, I::SubstsRef, I::Movability),
135 /// A type representing the types stored inside a generator.
136 /// This should only appear as part of the `GeneratorSubsts`.
138 /// Note that the captured variables for generators are stored separately
139 /// using a tuple in the same way as for closures.
141 /// Unlike upvars, the witness can reference lifetimes from
142 /// inside of the generator itself. To deal with them in
143 /// the type of the generator, we convert them to higher ranked
144 /// lifetimes bound by the witness itself.
146 /// Looking at the following example, the witness for this generator
147 /// may end up as something like `for<'a> [Vec<i32>, &'a Vec<i32>]`:
149 /// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?)
150 /// #![feature(generators)]
152 /// let x = &vec![3];
158 GeneratorWitness(I::BinderListTy),
160 /// The never type `!`.
163 /// A tuple type. For example, `(i32, bool)`.
166 /// The projection of an associated type. For example,
167 /// `<T as Trait<..>>::N`.
168 Projection(I::ProjectionTy),
170 /// Opaque (`impl Trait`) type found in a return type.
172 /// The `DefId` comes either from
173 /// * the `impl Trait` ast::Ty node,
174 /// * or the `type Foo = impl Trait` declaration
176 /// For RPIT the substitutions are for the generics of the function,
177 /// while for TAIT it is used for the generic parameters of the alias.
179 /// During codegen, `tcx.type_of(def_id)` can be used to get the underlying type.
180 Opaque(I::DefId, I::SubstsRef),
182 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
185 /// Bound type variable, used to represent the `'a` in `for<'a> fn(&'a ())`.
187 /// For canonical queries, we replace inference variables with bound variables,
188 /// so e.g. when checking whether `&'_ (): Trait<_>` holds, we canonicalize that to
189 /// `for<'a, T> &'a (): Trait<T>` and then convert the introduced bound variables
190 /// back to inference variables in a new inference context when inside of the query.
192 /// See the `rustc-dev-guide` for more details about
193 /// [higher-ranked trait bounds][1] and [canonical queries][2].
195 /// [1]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
196 /// [2]: https://rustc-dev-guide.rust-lang.org/traits/canonical-queries.html
197 Bound(DebruijnIndex, I::BoundTy),
199 /// A placeholder type, used during higher ranked subtyping to instantiate
201 Placeholder(I::PlaceholderType),
203 /// A type variable used during type checking.
205 /// Similar to placeholders, inference variables also live in a universe to
206 /// correctly deal with higher ranked types. Though unlike placeholders,
207 /// that universe is stored in the `InferCtxt` instead of directly
208 /// inside of the type.
211 /// A placeholder for a type which could not be computed; this is
212 /// propagated to avoid useless error messages.
213 Error(I::DelaySpanBugEmitted),
216 impl<I: Interner> TyKind<I> {
218 pub fn is_primitive(&self) -> bool {
219 matches!(self, Bool | Char | Int(_) | Uint(_) | Float(_))
223 // This is manually implemented for `TyKind` because `std::mem::discriminant`
224 // returns an opaque value that is `PartialEq` but not `PartialOrd`
226 const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
244 Generator(_, _, _) => 16,
245 GeneratorWitness(_) => 17,
252 Placeholder(_) => 24,
258 // This is manually implemented because a derive would require `I: Clone`
259 impl<I: Interner> Clone for TyKind<I> {
260 fn clone(&self) -> Self {
264 Int(i) => Int(i.clone()),
265 Uint(u) => Uint(u.clone()),
266 Float(f) => Float(f.clone()),
267 Adt(d, s) => Adt(d.clone(), s.clone()),
268 Foreign(d) => Foreign(d.clone()),
270 Array(t, c) => Array(t.clone(), c.clone()),
271 Slice(t) => Slice(t.clone()),
272 RawPtr(t) => RawPtr(t.clone()),
273 Ref(r, t, m) => Ref(r.clone(), t.clone(), m.clone()),
274 FnDef(d, s) => FnDef(d.clone(), s.clone()),
275 FnPtr(s) => FnPtr(s.clone()),
276 Dynamic(p, r, repr) => Dynamic(p.clone(), r.clone(), repr.clone()),
277 Closure(d, s) => Closure(d.clone(), s.clone()),
278 Generator(d, s, m) => Generator(d.clone(), s.clone(), m.clone()),
279 GeneratorWitness(g) => GeneratorWitness(g.clone()),
281 Tuple(t) => Tuple(t.clone()),
282 Projection(p) => Projection(p.clone()),
283 Opaque(d, s) => Opaque(d.clone(), s.clone()),
284 Param(p) => Param(p.clone()),
285 Bound(d, b) => Bound(d.clone(), b.clone()),
286 Placeholder(p) => Placeholder(p.clone()),
287 Infer(t) => Infer(t.clone()),
288 Error(e) => Error(e.clone()),
293 // This is manually implemented because a derive would require `I: PartialEq`
294 impl<I: Interner> PartialEq for TyKind<I> {
296 fn eq(&self, other: &TyKind<I>) -> bool {
297 let __self_vi = tykind_discriminant(self);
298 let __arg_1_vi = tykind_discriminant(other);
299 if __self_vi == __arg_1_vi {
300 match (&*self, &*other) {
301 (&Int(ref __self_0), &Int(ref __arg_1_0)) => __self_0 == __arg_1_0,
302 (&Uint(ref __self_0), &Uint(ref __arg_1_0)) => __self_0 == __arg_1_0,
303 (&Float(ref __self_0), &Float(ref __arg_1_0)) => __self_0 == __arg_1_0,
304 (&Adt(ref __self_0, ref __self_1), &Adt(ref __arg_1_0, ref __arg_1_1)) => {
305 __self_0 == __arg_1_0 && __self_1 == __arg_1_1
307 (&Foreign(ref __self_0), &Foreign(ref __arg_1_0)) => __self_0 == __arg_1_0,
308 (&Array(ref __self_0, ref __self_1), &Array(ref __arg_1_0, ref __arg_1_1)) => {
309 __self_0 == __arg_1_0 && __self_1 == __arg_1_1
311 (&Slice(ref __self_0), &Slice(ref __arg_1_0)) => __self_0 == __arg_1_0,
312 (&RawPtr(ref __self_0), &RawPtr(ref __arg_1_0)) => __self_0 == __arg_1_0,
314 &Ref(ref __self_0, ref __self_1, ref __self_2),
315 &Ref(ref __arg_1_0, ref __arg_1_1, ref __arg_1_2),
316 ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1 && __self_2 == __arg_1_2,
317 (&FnDef(ref __self_0, ref __self_1), &FnDef(ref __arg_1_0, ref __arg_1_1)) => {
318 __self_0 == __arg_1_0 && __self_1 == __arg_1_1
320 (&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => __self_0 == __arg_1_0,
322 &Dynamic(ref __self_0, ref __self_1, ref self_repr),
323 &Dynamic(ref __arg_1_0, ref __arg_1_1, ref arg_repr),
324 ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1 && self_repr == arg_repr,
325 (&Closure(ref __self_0, ref __self_1), &Closure(ref __arg_1_0, ref __arg_1_1)) => {
326 __self_0 == __arg_1_0 && __self_1 == __arg_1_1
329 &Generator(ref __self_0, ref __self_1, ref __self_2),
330 &Generator(ref __arg_1_0, ref __arg_1_1, ref __arg_1_2),
331 ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1 && __self_2 == __arg_1_2,
332 (&GeneratorWitness(ref __self_0), &GeneratorWitness(ref __arg_1_0)) => {
333 __self_0 == __arg_1_0
335 (&Tuple(ref __self_0), &Tuple(ref __arg_1_0)) => __self_0 == __arg_1_0,
336 (&Projection(ref __self_0), &Projection(ref __arg_1_0)) => __self_0 == __arg_1_0,
337 (&Opaque(ref __self_0, ref __self_1), &Opaque(ref __arg_1_0, ref __arg_1_1)) => {
338 __self_0 == __arg_1_0 && __self_1 == __arg_1_1
340 (&Param(ref __self_0), &Param(ref __arg_1_0)) => __self_0 == __arg_1_0,
341 (&Bound(ref __self_0, ref __self_1), &Bound(ref __arg_1_0, ref __arg_1_1)) => {
342 __self_0 == __arg_1_0 && __self_1 == __arg_1_1
344 (&Placeholder(ref __self_0), &Placeholder(ref __arg_1_0)) => __self_0 == __arg_1_0,
345 (&Infer(ref __self_0), &Infer(ref __arg_1_0)) => __self_0 == __arg_1_0,
346 (&Error(ref __self_0), &Error(ref __arg_1_0)) => __self_0 == __arg_1_0,
355 // This is manually implemented because a derive would require `I: Eq`
356 impl<I: Interner> Eq for TyKind<I> {}
358 // This is manually implemented because a derive would require `I: PartialOrd`
359 impl<I: Interner> PartialOrd for TyKind<I> {
361 fn partial_cmp(&self, other: &TyKind<I>) -> Option<Ordering> {
362 Some(Ord::cmp(self, other))
366 // This is manually implemented because a derive would require `I: Ord`
367 impl<I: Interner> Ord for TyKind<I> {
369 fn cmp(&self, other: &TyKind<I>) -> Ordering {
370 let __self_vi = tykind_discriminant(self);
371 let __arg_1_vi = tykind_discriminant(other);
372 if __self_vi == __arg_1_vi {
373 match (&*self, &*other) {
374 (&Int(ref __self_0), &Int(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
375 (&Uint(ref __self_0), &Uint(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
376 (&Float(ref __self_0), &Float(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
377 (&Adt(ref __self_0, ref __self_1), &Adt(ref __arg_1_0, ref __arg_1_1)) => {
378 match Ord::cmp(__self_0, __arg_1_0) {
379 Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
383 (&Foreign(ref __self_0), &Foreign(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
384 (&Array(ref __self_0, ref __self_1), &Array(ref __arg_1_0, ref __arg_1_1)) => {
385 match Ord::cmp(__self_0, __arg_1_0) {
386 Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
390 (&Slice(ref __self_0), &Slice(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
391 (&RawPtr(ref __self_0), &RawPtr(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
393 &Ref(ref __self_0, ref __self_1, ref __self_2),
394 &Ref(ref __arg_1_0, ref __arg_1_1, ref __arg_1_2),
395 ) => match Ord::cmp(__self_0, __arg_1_0) {
396 Ordering::Equal => match Ord::cmp(__self_1, __arg_1_1) {
397 Ordering::Equal => Ord::cmp(__self_2, __arg_1_2),
402 (&FnDef(ref __self_0, ref __self_1), &FnDef(ref __arg_1_0, ref __arg_1_1)) => {
403 match Ord::cmp(__self_0, __arg_1_0) {
404 Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
408 (&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
410 &Dynamic(ref __self_0, ref __self_1, ref self_repr),
411 &Dynamic(ref __arg_1_0, ref __arg_1_1, ref arg_repr),
412 ) => match Ord::cmp(__self_0, __arg_1_0) {
413 Ordering::Equal => match Ord::cmp(__self_1, __arg_1_1) {
414 Ordering::Equal => Ord::cmp(self_repr, arg_repr),
419 (&Closure(ref __self_0, ref __self_1), &Closure(ref __arg_1_0, ref __arg_1_1)) => {
420 match Ord::cmp(__self_0, __arg_1_0) {
421 Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
426 &Generator(ref __self_0, ref __self_1, ref __self_2),
427 &Generator(ref __arg_1_0, ref __arg_1_1, ref __arg_1_2),
428 ) => match Ord::cmp(__self_0, __arg_1_0) {
429 Ordering::Equal => match Ord::cmp(__self_1, __arg_1_1) {
430 Ordering::Equal => Ord::cmp(__self_2, __arg_1_2),
435 (&GeneratorWitness(ref __self_0), &GeneratorWitness(ref __arg_1_0)) => {
436 Ord::cmp(__self_0, __arg_1_0)
438 (&Tuple(ref __self_0), &Tuple(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
439 (&Projection(ref __self_0), &Projection(ref __arg_1_0)) => {
440 Ord::cmp(__self_0, __arg_1_0)
442 (&Opaque(ref __self_0, ref __self_1), &Opaque(ref __arg_1_0, ref __arg_1_1)) => {
443 match Ord::cmp(__self_0, __arg_1_0) {
444 Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
448 (&Param(ref __self_0), &Param(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
449 (&Bound(ref __self_0, ref __self_1), &Bound(ref __arg_1_0, ref __arg_1_1)) => {
450 match Ord::cmp(__self_0, __arg_1_0) {
451 Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
455 (&Placeholder(ref __self_0), &Placeholder(ref __arg_1_0)) => {
456 Ord::cmp(__self_0, __arg_1_0)
458 (&Infer(ref __self_0), &Infer(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
459 (&Error(ref __self_0), &Error(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
460 _ => Ordering::Equal,
463 Ord::cmp(&__self_vi, &__arg_1_vi)
468 // This is manually implemented because a derive would require `I: Hash`
469 impl<I: Interner> hash::Hash for TyKind<I> {
470 fn hash<__H: hash::Hasher>(&self, state: &mut __H) -> () {
472 (&Int(ref __self_0),) => {
473 hash::Hash::hash(&tykind_discriminant(self), state);
474 hash::Hash::hash(__self_0, state)
476 (&Uint(ref __self_0),) => {
477 hash::Hash::hash(&tykind_discriminant(self), state);
478 hash::Hash::hash(__self_0, state)
480 (&Float(ref __self_0),) => {
481 hash::Hash::hash(&tykind_discriminant(self), state);
482 hash::Hash::hash(__self_0, state)
484 (&Adt(ref __self_0, ref __self_1),) => {
485 hash::Hash::hash(&tykind_discriminant(self), state);
486 hash::Hash::hash(__self_0, state);
487 hash::Hash::hash(__self_1, state)
489 (&Foreign(ref __self_0),) => {
490 hash::Hash::hash(&tykind_discriminant(self), state);
491 hash::Hash::hash(__self_0, state)
493 (&Array(ref __self_0, ref __self_1),) => {
494 hash::Hash::hash(&tykind_discriminant(self), state);
495 hash::Hash::hash(__self_0, state);
496 hash::Hash::hash(__self_1, state)
498 (&Slice(ref __self_0),) => {
499 hash::Hash::hash(&tykind_discriminant(self), state);
500 hash::Hash::hash(__self_0, state)
502 (&RawPtr(ref __self_0),) => {
503 hash::Hash::hash(&tykind_discriminant(self), state);
504 hash::Hash::hash(__self_0, state)
506 (&Ref(ref __self_0, ref __self_1, ref __self_2),) => {
507 hash::Hash::hash(&tykind_discriminant(self), state);
508 hash::Hash::hash(__self_0, state);
509 hash::Hash::hash(__self_1, state);
510 hash::Hash::hash(__self_2, state)
512 (&FnDef(ref __self_0, ref __self_1),) => {
513 hash::Hash::hash(&tykind_discriminant(self), state);
514 hash::Hash::hash(__self_0, state);
515 hash::Hash::hash(__self_1, state)
517 (&FnPtr(ref __self_0),) => {
518 hash::Hash::hash(&tykind_discriminant(self), state);
519 hash::Hash::hash(__self_0, state)
521 (&Dynamic(ref __self_0, ref __self_1, ref repr),) => {
522 hash::Hash::hash(&tykind_discriminant(self), state);
523 hash::Hash::hash(__self_0, state);
524 hash::Hash::hash(__self_1, state);
525 hash::Hash::hash(repr, state)
527 (&Closure(ref __self_0, ref __self_1),) => {
528 hash::Hash::hash(&tykind_discriminant(self), state);
529 hash::Hash::hash(__self_0, state);
530 hash::Hash::hash(__self_1, state)
532 (&Generator(ref __self_0, ref __self_1, ref __self_2),) => {
533 hash::Hash::hash(&tykind_discriminant(self), state);
534 hash::Hash::hash(__self_0, state);
535 hash::Hash::hash(__self_1, state);
536 hash::Hash::hash(__self_2, state)
538 (&GeneratorWitness(ref __self_0),) => {
539 hash::Hash::hash(&tykind_discriminant(self), state);
540 hash::Hash::hash(__self_0, state)
542 (&Tuple(ref __self_0),) => {
543 hash::Hash::hash(&tykind_discriminant(self), state);
544 hash::Hash::hash(__self_0, state)
546 (&Projection(ref __self_0),) => {
547 hash::Hash::hash(&tykind_discriminant(self), state);
548 hash::Hash::hash(__self_0, state)
550 (&Opaque(ref __self_0, ref __self_1),) => {
551 hash::Hash::hash(&tykind_discriminant(self), state);
552 hash::Hash::hash(__self_0, state);
553 hash::Hash::hash(__self_1, state)
555 (&Param(ref __self_0),) => {
556 hash::Hash::hash(&tykind_discriminant(self), state);
557 hash::Hash::hash(__self_0, state)
559 (&Bound(ref __self_0, ref __self_1),) => {
560 hash::Hash::hash(&tykind_discriminant(self), state);
561 hash::Hash::hash(__self_0, state);
562 hash::Hash::hash(__self_1, state)
564 (&Placeholder(ref __self_0),) => {
565 hash::Hash::hash(&tykind_discriminant(self), state);
566 hash::Hash::hash(__self_0, state)
568 (&Infer(ref __self_0),) => {
569 hash::Hash::hash(&tykind_discriminant(self), state);
570 hash::Hash::hash(__self_0, state)
572 (&Error(ref __self_0),) => {
573 hash::Hash::hash(&tykind_discriminant(self), state);
574 hash::Hash::hash(__self_0, state)
576 _ => hash::Hash::hash(&tykind_discriminant(self), state),
581 // This is manually implemented because a derive would require `I: Debug`
582 impl<I: Interner> fmt::Debug for TyKind<I> {
583 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
586 Bool => Formatter::write_str(f, "Bool"),
587 Char => Formatter::write_str(f, "Char"),
588 Int(f0) => Formatter::debug_tuple_field1_finish(f, "Int", f0),
589 Uint(f0) => Formatter::debug_tuple_field1_finish(f, "Uint", f0),
590 Float(f0) => Formatter::debug_tuple_field1_finish(f, "Float", f0),
591 Adt(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Adt", f0, f1),
592 Foreign(f0) => Formatter::debug_tuple_field1_finish(f, "Foreign", f0),
593 Str => Formatter::write_str(f, "Str"),
594 Array(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Array", f0, f1),
595 Slice(f0) => Formatter::debug_tuple_field1_finish(f, "Slice", f0),
596 RawPtr(f0) => Formatter::debug_tuple_field1_finish(f, "RawPtr", f0),
597 Ref(f0, f1, f2) => Formatter::debug_tuple_field3_finish(f, "Ref", f0, f1, f2),
598 FnDef(f0, f1) => Formatter::debug_tuple_field2_finish(f, "FnDef", f0, f1),
599 FnPtr(f0) => Formatter::debug_tuple_field1_finish(f, "FnPtr", f0),
600 Dynamic(f0, f1, f2) => Formatter::debug_tuple_field3_finish(f, "Dynamic", f0, f1, f2),
601 Closure(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Closure", f0, f1),
602 Generator(f0, f1, f2) => {
603 Formatter::debug_tuple_field3_finish(f, "Generator", f0, f1, f2)
605 GeneratorWitness(f0) => Formatter::debug_tuple_field1_finish(f, "GeneratorWitness", f0),
606 Never => Formatter::write_str(f, "Never"),
607 Tuple(f0) => Formatter::debug_tuple_field1_finish(f, "Tuple", f0),
608 Projection(f0) => Formatter::debug_tuple_field1_finish(f, "Projection", f0),
609 Opaque(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Opaque", f0, f1),
610 Param(f0) => Formatter::debug_tuple_field1_finish(f, "Param", f0),
611 Bound(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Bound", f0, f1),
612 Placeholder(f0) => Formatter::debug_tuple_field1_finish(f, "Placeholder", f0),
613 Infer(f0) => Formatter::debug_tuple_field1_finish(f, "Infer", f0),
614 TyKind::Error(f0) => Formatter::debug_tuple_field1_finish(f, "Error", f0),
619 // This is manually implemented because a derive would require `I: Encodable`
620 impl<I: Interner, E: TyEncoder> Encodable<E> for TyKind<I>
622 I::DelaySpanBugEmitted: Encodable<E>,
623 I::AdtDef: Encodable<E>,
624 I::SubstsRef: Encodable<E>,
625 I::DefId: Encodable<E>,
627 I::Const: Encodable<E>,
628 I::Region: Encodable<E>,
629 I::TypeAndMut: Encodable<E>,
630 I::Mutability: Encodable<E>,
631 I::Movability: Encodable<E>,
632 I::PolyFnSig: Encodable<E>,
633 I::ListBinderExistentialPredicate: Encodable<E>,
634 I::BinderListTy: Encodable<E>,
635 I::ListTy: Encodable<E>,
636 I::ProjectionTy: Encodable<E>,
637 I::ParamTy: Encodable<E>,
638 I::BoundTy: Encodable<E>,
639 I::PlaceholderType: Encodable<E>,
640 I::InferTy: Encodable<E>,
641 I::DelaySpanBugEmitted: Encodable<E>,
642 I::PredicateKind: Encodable<E>,
643 I::AllocId: Encodable<E>,
645 fn encode(&self, e: &mut E) {
646 let disc = tykind_discriminant(self);
648 Bool => e.emit_enum_variant(disc, |_| {}),
649 Char => e.emit_enum_variant(disc, |_| {}),
650 Int(i) => e.emit_enum_variant(disc, |e| {
653 Uint(u) => e.emit_enum_variant(disc, |e| {
656 Float(f) => e.emit_enum_variant(disc, |e| {
659 Adt(adt, substs) => e.emit_enum_variant(disc, |e| {
663 Foreign(def_id) => e.emit_enum_variant(disc, |e| {
666 Str => e.emit_enum_variant(disc, |_| {}),
667 Array(t, c) => e.emit_enum_variant(disc, |e| {
671 Slice(t) => e.emit_enum_variant(disc, |e| {
674 RawPtr(tam) => e.emit_enum_variant(disc, |e| {
677 Ref(r, t, m) => e.emit_enum_variant(disc, |e| {
682 FnDef(def_id, substs) => e.emit_enum_variant(disc, |e| {
686 FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| {
689 Dynamic(l, r, repr) => e.emit_enum_variant(disc, |e| {
694 Closure(def_id, substs) => e.emit_enum_variant(disc, |e| {
698 Generator(def_id, substs, m) => e.emit_enum_variant(disc, |e| {
703 GeneratorWitness(b) => e.emit_enum_variant(disc, |e| {
706 Never => e.emit_enum_variant(disc, |_| {}),
707 Tuple(substs) => e.emit_enum_variant(disc, |e| {
710 Projection(p) => e.emit_enum_variant(disc, |e| {
713 Opaque(def_id, substs) => e.emit_enum_variant(disc, |e| {
717 Param(p) => e.emit_enum_variant(disc, |e| {
720 Bound(d, b) => e.emit_enum_variant(disc, |e| {
724 Placeholder(p) => e.emit_enum_variant(disc, |e| {
727 Infer(i) => e.emit_enum_variant(disc, |e| {
730 Error(d) => e.emit_enum_variant(disc, |e| {
737 // This is manually implemented because a derive would require `I: Decodable`
738 impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for TyKind<I>
740 I::DelaySpanBugEmitted: Decodable<D>,
741 I::AdtDef: Decodable<D>,
742 I::SubstsRef: Decodable<D>,
743 I::DefId: Decodable<D>,
745 I::Const: Decodable<D>,
746 I::Region: Decodable<D>,
747 I::TypeAndMut: Decodable<D>,
748 I::Mutability: Decodable<D>,
749 I::Movability: Decodable<D>,
750 I::PolyFnSig: Decodable<D>,
751 I::ListBinderExistentialPredicate: Decodable<D>,
752 I::BinderListTy: Decodable<D>,
753 I::ListTy: Decodable<D>,
754 I::ProjectionTy: Decodable<D>,
755 I::ParamTy: Decodable<D>,
756 I::BoundTy: Decodable<D>,
757 I::PlaceholderType: Decodable<D>,
758 I::InferTy: Decodable<D>,
759 I::DelaySpanBugEmitted: Decodable<D>,
760 I::PredicateKind: Decodable<D>,
761 I::AllocId: Decodable<D>,
763 fn decode(d: &mut D) -> Self {
764 match Decoder::read_usize(d) {
767 2 => Int(Decodable::decode(d)),
768 3 => Uint(Decodable::decode(d)),
769 4 => Float(Decodable::decode(d)),
770 5 => Adt(Decodable::decode(d), Decodable::decode(d)),
771 6 => Foreign(Decodable::decode(d)),
773 8 => Array(Decodable::decode(d), Decodable::decode(d)),
774 9 => Slice(Decodable::decode(d)),
775 10 => RawPtr(Decodable::decode(d)),
776 11 => Ref(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
777 12 => FnDef(Decodable::decode(d), Decodable::decode(d)),
778 13 => FnPtr(Decodable::decode(d)),
779 14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
780 15 => Closure(Decodable::decode(d), Decodable::decode(d)),
781 16 => Generator(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
782 17 => GeneratorWitness(Decodable::decode(d)),
784 19 => Tuple(Decodable::decode(d)),
785 20 => Projection(Decodable::decode(d)),
786 21 => Opaque(Decodable::decode(d), Decodable::decode(d)),
787 22 => Param(Decodable::decode(d)),
788 23 => Bound(Decodable::decode(d), Decodable::decode(d)),
789 24 => Placeholder(Decodable::decode(d)),
790 25 => Infer(Decodable::decode(d)),
791 26 => Error(Decodable::decode(d)),
795 "invalid enum variant tag while decoding `{}`, expected 0..{}",
803 // This is not a derived impl because a derive would require `I: HashStable`
804 #[allow(rustc::usage_of_ty_tykind)]
805 impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for TyKind<I>
807 I::AdtDef: HashStable<CTX>,
808 I::DefId: HashStable<CTX>,
809 I::SubstsRef: HashStable<CTX>,
810 I::Ty: HashStable<CTX>,
811 I::Const: HashStable<CTX>,
812 I::TypeAndMut: HashStable<CTX>,
813 I::PolyFnSig: HashStable<CTX>,
814 I::ListBinderExistentialPredicate: HashStable<CTX>,
815 I::Region: HashStable<CTX>,
816 I::Movability: HashStable<CTX>,
817 I::Mutability: HashStable<CTX>,
818 I::BinderListTy: HashStable<CTX>,
819 I::ListTy: HashStable<CTX>,
820 I::ProjectionTy: HashStable<CTX>,
821 I::BoundTy: HashStable<CTX>,
822 I::ParamTy: HashStable<CTX>,
823 I::PlaceholderType: HashStable<CTX>,
824 I::InferTy: HashStable<CTX>,
825 I::DelaySpanBugEmitted: HashStable<CTX>,
831 __hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
833 std::mem::discriminant(self).hash_stable(__hcx, __hasher);
838 i.hash_stable(__hcx, __hasher);
841 u.hash_stable(__hcx, __hasher);
844 f.hash_stable(__hcx, __hasher);
846 Adt(adt, substs) => {
847 adt.hash_stable(__hcx, __hasher);
848 substs.hash_stable(__hcx, __hasher);
851 def_id.hash_stable(__hcx, __hasher);
855 t.hash_stable(__hcx, __hasher);
856 c.hash_stable(__hcx, __hasher);
859 t.hash_stable(__hcx, __hasher);
862 tam.hash_stable(__hcx, __hasher);
865 r.hash_stable(__hcx, __hasher);
866 t.hash_stable(__hcx, __hasher);
867 m.hash_stable(__hcx, __hasher);
869 FnDef(def_id, substs) => {
870 def_id.hash_stable(__hcx, __hasher);
871 substs.hash_stable(__hcx, __hasher);
873 FnPtr(polyfnsig) => {
874 polyfnsig.hash_stable(__hcx, __hasher);
876 Dynamic(l, r, repr) => {
877 l.hash_stable(__hcx, __hasher);
878 r.hash_stable(__hcx, __hasher);
879 repr.hash_stable(__hcx, __hasher);
881 Closure(def_id, substs) => {
882 def_id.hash_stable(__hcx, __hasher);
883 substs.hash_stable(__hcx, __hasher);
885 Generator(def_id, substs, m) => {
886 def_id.hash_stable(__hcx, __hasher);
887 substs.hash_stable(__hcx, __hasher);
888 m.hash_stable(__hcx, __hasher);
890 GeneratorWitness(b) => {
891 b.hash_stable(__hcx, __hasher);
895 substs.hash_stable(__hcx, __hasher);
898 p.hash_stable(__hcx, __hasher);
900 Opaque(def_id, substs) => {
901 def_id.hash_stable(__hcx, __hasher);
902 substs.hash_stable(__hcx, __hasher);
905 p.hash_stable(__hcx, __hasher);
908 d.hash_stable(__hcx, __hasher);
909 b.hash_stable(__hcx, __hasher);
912 p.hash_stable(__hcx, __hasher);
915 i.hash_stable(__hcx, __hasher);
918 d.hash_stable(__hcx, __hasher);
924 /// Representation of regions. Note that the NLL checker uses a distinct
925 /// representation of regions. For this reason, it internally replaces all the
926 /// regions with inference variables -- the index of the variable is then used
927 /// to index into internal NLL data structures. See `rustc_const_eval::borrow_check`
928 /// module for more information.
930 /// Note: operations are on the wrapper `Region` type, which is interned,
931 /// rather than this type.
933 /// ## The Region lattice within a given function
935 /// In general, the region lattice looks like
938 /// static ----------+-----...------+ (greatest)
940 /// early-bound and | |
944 /// empty(root) placeholder(U1) |
946 /// | / placeholder(Un)
951 /// empty(Un) -------- (smallest)
954 /// Early-bound/free regions are the named lifetimes in scope from the
955 /// function declaration. They have relationships to one another
956 /// determined based on the declared relationships from the
959 /// Note that inference variables and bound regions are not included
960 /// in this diagram. In the case of inference variables, they should
961 /// be inferred to some other region from the diagram. In the case of
962 /// bound regions, they are excluded because they don't make sense to
963 /// include -- the diagram indicates the relationship between free
966 /// ## Inference variables
968 /// During region inference, we sometimes create inference variables,
969 /// represented as `ReVar`. These will be inferred by the code in
970 /// `infer::lexical_region_resolve` to some free region from the
971 /// lattice above (the minimal region that meets the
974 /// During NLL checking, where regions are defined differently, we
975 /// also use `ReVar` -- in that case, the index is used to index into
976 /// the NLL region checker's data structures. The variable may in fact
977 /// represent either a free region or an inference variable, in that
982 /// These are regions that are stored behind a binder and must be substituted
983 /// with some concrete region before being used. There are two kind of
984 /// bound regions: early-bound, which are bound in an item's `Generics`,
985 /// and are substituted by an `InternalSubsts`, and late-bound, which are part of
986 /// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by
987 /// the likes of `liberate_late_bound_regions`. The distinction exists
988 /// because higher-ranked lifetimes aren't supported in all places. See [1][2].
990 /// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
991 /// outside their binder, e.g., in types passed to type inference, and
992 /// should first be substituted (by placeholder regions, free regions,
993 /// or region variables).
995 /// ## Placeholder and Free Regions
997 /// One often wants to work with bound regions without knowing their precise
998 /// identity. For example, when checking a function, the lifetime of a borrow
999 /// can end up being assigned to some region parameter. In these cases,
1000 /// it must be ensured that bounds on the region can't be accidentally
1001 /// assumed without being checked.
1003 /// To do this, we replace the bound regions with placeholder markers,
1004 /// which don't satisfy any relation not explicitly provided.
1006 /// There are two kinds of placeholder regions in rustc: `ReFree` and
1007 /// `RePlaceholder`. When checking an item's body, `ReFree` is supposed
1008 /// to be used. These also support explicit bounds: both the internally-stored
1009 /// *scope*, which the region is assumed to outlive, as well as other
1010 /// relations stored in the `FreeRegionMap`. Note that these relations
1011 /// aren't checked when you `make_subregion` (or `eq_types`), only by
1012 /// `resolve_regions_and_report_errors`.
1014 /// When working with higher-ranked types, some region relations aren't
1015 /// yet known, so you can't just call `resolve_regions_and_report_errors`.
1016 /// `RePlaceholder` is designed for this purpose. In these contexts,
1017 /// there's also the risk that some inference variable laying around will
1018 /// get unified with your placeholder region: if you want to check whether
1019 /// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
1020 /// with a placeholder region `'%a`, the variable `'_` would just be
1021 /// instantiated to the placeholder region `'%a`, which is wrong because
1022 /// the inference variable is supposed to satisfy the relation
1023 /// *for every value of the placeholder region*. To ensure that doesn't
1024 /// happen, you can use `leak_check`. This is more clearly explained
1025 /// by the [rustc dev guide].
1027 /// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
1028 /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
1029 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
1030 pub enum RegionKind<I: Interner> {
1031 /// Region bound in a type or fn declaration which will be
1032 /// substituted 'early' -- that is, at the same time when type
1033 /// parameters are substituted.
1034 ReEarlyBound(I::EarlyBoundRegion),
1036 /// Region bound in a function scope, which will be substituted when the
1037 /// function is called.
1038 ReLateBound(DebruijnIndex, I::BoundRegion),
1040 /// When checking a function body, the types of all arguments and so forth
1041 /// that refer to bound region parameters are modified to refer to free
1042 /// region parameters.
1043 ReFree(I::FreeRegion),
1045 /// Static data that has an "infinite" lifetime. Top in the region lattice.
1048 /// A region variable. Should not exist outside of type inference.
1049 ReVar(I::RegionVid),
1051 /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
1052 /// Should not exist outside of type inference.
1053 RePlaceholder(I::PlaceholderRegion),
1055 /// Erased region, used by trait selection, in MIR and during codegen.
1059 // This is manually implemented for `RegionKind` because `std::mem::discriminant`
1060 // returns an opaque value that is `PartialEq` but not `PartialOrd`
1062 const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
1064 ReEarlyBound(_) => 0,
1065 ReLateBound(_, _) => 1,
1069 RePlaceholder(_) => 5,
1074 // This is manually implemented because a derive would require `I: Copy`
1075 impl<I: Interner> Copy for RegionKind<I>
1077 I::EarlyBoundRegion: Copy,
1078 I::BoundRegion: Copy,
1079 I::FreeRegion: Copy,
1081 I::PlaceholderRegion: Copy,
1085 // This is manually implemented because a derive would require `I: Clone`
1086 impl<I: Interner> Clone for RegionKind<I> {
1087 fn clone(&self) -> Self {
1089 ReEarlyBound(a) => ReEarlyBound(a.clone()),
1090 ReLateBound(a, b) => ReLateBound(a.clone(), b.clone()),
1091 ReFree(a) => ReFree(a.clone()),
1092 ReStatic => ReStatic,
1093 ReVar(a) => ReVar(a.clone()),
1094 RePlaceholder(a) => RePlaceholder(a.clone()),
1095 ReErased => ReErased,
1100 // This is manually implemented because a derive would require `I: PartialEq`
1101 impl<I: Interner> PartialEq for RegionKind<I> {
1103 fn eq(&self, other: &RegionKind<I>) -> bool {
1104 let __self_vi = regionkind_discriminant(self);
1105 let __arg_1_vi = regionkind_discriminant(other);
1106 if __self_vi == __arg_1_vi {
1107 match (&*self, &*other) {
1108 (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
1109 __self_0 == __arg_1_0
1112 &ReLateBound(ref __self_0, ref __self_1),
1113 &ReLateBound(ref __arg_1_0, ref __arg_1_1),
1114 ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1,
1115 (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => __self_0 == __arg_1_0,
1116 (&ReStatic, &ReStatic) => true,
1117 (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => __self_0 == __arg_1_0,
1118 (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
1119 __self_0 == __arg_1_0
1121 (&ReErased, &ReErased) => true,
1130 // This is manually implemented because a derive would require `I: Eq`
1131 impl<I: Interner> Eq for RegionKind<I> {}
1133 // This is manually implemented because a derive would require `I: PartialOrd`
1134 impl<I: Interner> PartialOrd for RegionKind<I> {
1136 fn partial_cmp(&self, other: &RegionKind<I>) -> Option<Ordering> {
1137 Some(Ord::cmp(self, other))
1141 // This is manually implemented because a derive would require `I: Ord`
1142 impl<I: Interner> Ord for RegionKind<I> {
1144 fn cmp(&self, other: &RegionKind<I>) -> Ordering {
1145 let __self_vi = regionkind_discriminant(self);
1146 let __arg_1_vi = regionkind_discriminant(other);
1147 if __self_vi == __arg_1_vi {
1148 match (&*self, &*other) {
1149 (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
1150 Ord::cmp(__self_0, __arg_1_0)
1153 &ReLateBound(ref __self_0, ref __self_1),
1154 &ReLateBound(ref __arg_1_0, ref __arg_1_1),
1155 ) => match Ord::cmp(__self_0, __arg_1_0) {
1156 Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
1159 (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
1160 (&ReStatic, &ReStatic) => Ordering::Equal,
1161 (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
1162 (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
1163 Ord::cmp(__self_0, __arg_1_0)
1165 (&ReErased, &ReErased) => Ordering::Equal,
1166 _ => Ordering::Equal,
1169 Ord::cmp(&__self_vi, &__arg_1_vi)
1174 // This is manually implemented because a derive would require `I: Hash`
1175 impl<I: Interner> hash::Hash for RegionKind<I> {
1176 fn hash<__H: hash::Hasher>(&self, state: &mut __H) -> () {
1178 (&ReEarlyBound(ref __self_0),) => {
1179 hash::Hash::hash(®ionkind_discriminant(self), state);
1180 hash::Hash::hash(__self_0, state)
1182 (&ReLateBound(ref __self_0, ref __self_1),) => {
1183 hash::Hash::hash(®ionkind_discriminant(self), state);
1184 hash::Hash::hash(__self_0, state);
1185 hash::Hash::hash(__self_1, state)
1187 (&ReFree(ref __self_0),) => {
1188 hash::Hash::hash(®ionkind_discriminant(self), state);
1189 hash::Hash::hash(__self_0, state)
1192 hash::Hash::hash(®ionkind_discriminant(self), state);
1194 (&ReVar(ref __self_0),) => {
1195 hash::Hash::hash(®ionkind_discriminant(self), state);
1196 hash::Hash::hash(__self_0, state)
1198 (&RePlaceholder(ref __self_0),) => {
1199 hash::Hash::hash(®ionkind_discriminant(self), state);
1200 hash::Hash::hash(__self_0, state)
1203 hash::Hash::hash(®ionkind_discriminant(self), state);
1209 // This is manually implemented because a derive would require `I: Debug`
1210 impl<I: Interner> fmt::Debug for RegionKind<I> {
1211 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1213 ReEarlyBound(ref data) => write!(f, "ReEarlyBound({:?})", data),
1215 ReLateBound(binder_id, ref bound_region) => {
1216 write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
1219 ReFree(ref fr) => fr.fmt(f),
1221 ReStatic => write!(f, "ReStatic"),
1223 ReVar(ref vid) => vid.fmt(f),
1225 RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
1227 ReErased => write!(f, "ReErased"),
1232 // This is manually implemented because a derive would require `I: Encodable`
1233 impl<I: Interner, E: TyEncoder> Encodable<E> for RegionKind<I>
1235 I::EarlyBoundRegion: Encodable<E>,
1236 I::BoundRegion: Encodable<E>,
1237 I::FreeRegion: Encodable<E>,
1238 I::RegionVid: Encodable<E>,
1239 I::PlaceholderRegion: Encodable<E>,
1241 fn encode(&self, e: &mut E) {
1242 let disc = regionkind_discriminant(self);
1244 ReEarlyBound(a) => e.emit_enum_variant(disc, |e| {
1247 ReLateBound(a, b) => e.emit_enum_variant(disc, |e| {
1251 ReFree(a) => e.emit_enum_variant(disc, |e| {
1254 ReStatic => e.emit_enum_variant(disc, |_| {}),
1255 ReVar(a) => e.emit_enum_variant(disc, |e| {
1258 RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
1261 ReErased => e.emit_enum_variant(disc, |_| {}),
1266 // This is manually implemented because a derive would require `I: Decodable`
1267 impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for RegionKind<I>
1269 I::EarlyBoundRegion: Decodable<D>,
1270 I::BoundRegion: Decodable<D>,
1271 I::FreeRegion: Decodable<D>,
1272 I::RegionVid: Decodable<D>,
1273 I::PlaceholderRegion: Decodable<D>,
1275 fn decode(d: &mut D) -> Self {
1276 match Decoder::read_usize(d) {
1277 0 => ReEarlyBound(Decodable::decode(d)),
1278 1 => ReLateBound(Decodable::decode(d), Decodable::decode(d)),
1279 2 => ReFree(Decodable::decode(d)),
1281 4 => ReVar(Decodable::decode(d)),
1282 5 => RePlaceholder(Decodable::decode(d)),
1287 "invalid enum variant tag while decoding `{}`, expected 0..{}",
1295 // This is not a derived impl because a derive would require `I: HashStable`
1296 impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for RegionKind<I>
1298 I::EarlyBoundRegion: HashStable<CTX>,
1299 I::BoundRegion: HashStable<CTX>,
1300 I::FreeRegion: HashStable<CTX>,
1301 I::RegionVid: HashStable<CTX>,
1302 I::PlaceholderRegion: HashStable<CTX>,
1308 hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
1310 std::mem::discriminant(self).hash_stable(hcx, hasher);
1312 ReErased | ReStatic => {
1313 // No variant fields to hash for these ...
1315 ReLateBound(db, br) => {
1316 db.hash_stable(hcx, hasher);
1317 br.hash_stable(hcx, hasher);
1319 ReEarlyBound(eb) => {
1320 eb.hash_stable(hcx, hasher);
1322 ReFree(ref free_region) => {
1323 free_region.hash_stable(hcx, hasher);
1325 RePlaceholder(p) => {
1326 p.hash_stable(hcx, hasher);
1329 reg.hash_stable(hcx, hasher);