From 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:50 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_type_ir/src/sty.rs | 156 +++++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 44 deletions(-) (limited to 'compiler/rustc_type_ir/src/sty.rs') diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 5f29588ae..ebe2b76ae 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -26,11 +26,9 @@ pub enum DynKind { Dyn, /// A sized `dyn* Trait` object /// - /// These objects are represented as a `(data, vtable)` pair where `data` is a ptr-sized value - /// (often a pointer to the real object, but not necessarily) and `vtable` is a pointer to - /// the vtable for `dyn* Trait`. The representation is essentially the same as `&dyn Trait` - /// or similar, but the drop function included in the vtable is responsible for freeing the - /// underlying storage if needed. This allows a `dyn*` object to be treated agnostically with + /// These objects are represented as a `(data, vtable)` pair where `data` is a value of some + /// ptr-sized and ptr-aligned dynamically determined type `T` and `vtable` is a pointer to the + /// vtable of `impl T for Trait`. This allows a `dyn*` object to be treated agnostically with /// respect to whether it points to a `Box`, `Rc`, etc. DynStar, } @@ -160,6 +158,32 @@ pub enum TyKind { /// ``` GeneratorWitness(I::BinderListTy), + /// A type representing the types stored inside a generator. + /// This should only appear as part of the `GeneratorSubsts`. + /// + /// Unlike upvars, the witness can reference lifetimes from + /// inside of the generator itself. To deal with them in + /// the type of the generator, we convert them to higher ranked + /// lifetimes bound by the witness itself. + /// + /// This variant is only using when `drop_tracking_mir` is set. + /// This contains the `DefId` and the `SubstRef` of the generator. + /// The actual witness types are computed on MIR by the `mir_generator_witnesses` query. + /// + /// Looking at the following example, the witness for this generator + /// may end up as something like `for<'a> [Vec, &'a Vec]`: + /// + /// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?) + /// #![feature(generators)] + /// |a| { + /// let x = &vec![3]; + /// yield a; + /// yield x[0]; + /// } + /// # ; + /// ``` + GeneratorWitnessMIR(I::DefId, I::SubstsRef), + /// The never type `!`. Never, @@ -241,6 +265,7 @@ const fn tykind_discriminant(value: &TyKind) -> usize { Placeholder(_) => 23, Infer(_) => 24, Error(_) => 25, + GeneratorWitnessMIR(_, _) => 26, } } @@ -266,6 +291,7 @@ impl Clone for TyKind { Closure(d, s) => Closure(d.clone(), s.clone()), Generator(d, s, m) => Generator(d.clone(), s.clone(), m.clone()), GeneratorWitness(g) => GeneratorWitness(g.clone()), + GeneratorWitnessMIR(d, s) => GeneratorWitnessMIR(d.clone(), s.clone()), Never => Never, Tuple(t) => Tuple(t.clone()), Alias(k, p) => Alias(*k, p.clone()), @@ -282,43 +308,51 @@ impl Clone for TyKind { impl PartialEq for TyKind { #[inline] fn eq(&self, other: &TyKind) -> bool { - tykind_discriminant(self) == tykind_discriminant(other) - && match (self, other) { - (Int(a_i), Int(b_i)) => a_i == b_i, - (Uint(a_u), Uint(b_u)) => a_u == b_u, - (Float(a_f), Float(b_f)) => a_f == b_f, - (Adt(a_d, a_s), Adt(b_d, b_s)) => a_d == b_d && a_s == b_s, - (Foreign(a_d), Foreign(b_d)) => a_d == b_d, - (Array(a_t, a_c), Array(b_t, b_c)) => a_t == b_t && a_c == b_c, - (Slice(a_t), Slice(b_t)) => a_t == b_t, - (RawPtr(a_t), RawPtr(b_t)) => a_t == b_t, - (Ref(a_r, a_t, a_m), Ref(b_r, b_t, b_m)) => a_r == b_r && a_t == b_t && a_m == b_m, - (FnDef(a_d, a_s), FnDef(b_d, b_s)) => a_d == b_d && a_s == b_s, - (FnPtr(a_s), FnPtr(b_s)) => a_s == b_s, - (Dynamic(a_p, a_r, a_repr), Dynamic(b_p, b_r, b_repr)) => { - a_p == b_p && a_r == b_r && a_repr == b_repr - } - (Closure(a_d, a_s), Closure(b_d, b_s)) => a_d == b_d && a_s == b_s, - (Generator(a_d, a_s, a_m), Generator(b_d, b_s, b_m)) => { - a_d == b_d && a_s == b_s && a_m == b_m - } - (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g == b_g, - (Tuple(a_t), Tuple(b_t)) => a_t == b_t, - (Alias(a_i, a_p), Alias(b_i, b_p)) => a_i == b_i && a_p == b_p, - (Param(a_p), Param(b_p)) => a_p == b_p, - (Bound(a_d, a_b), Bound(b_d, b_b)) => a_d == b_d && a_b == b_b, - (Placeholder(a_p), Placeholder(b_p)) => a_p == b_p, - (Infer(a_t), Infer(b_t)) => a_t == b_t, - (Error(a_e), Error(b_e)) => a_e == b_e, - (Bool, Bool) | (Char, Char) | (Str, Str) | (Never, Never) => true, - _ => { - debug_assert!( - false, - "This branch must be unreachable, maybe the match is missing an arm? self = self = {self:?}, other = {other:?}" - ); - true - } + // You might expect this `match` to be preceded with this: + // + // tykind_discriminant(self) == tykind_discriminant(other) && + // + // but the data patterns in practice are such that a comparison + // succeeds 99%+ of the time, and it's faster to omit it. + match (self, other) { + (Int(a_i), Int(b_i)) => a_i == b_i, + (Uint(a_u), Uint(b_u)) => a_u == b_u, + (Float(a_f), Float(b_f)) => a_f == b_f, + (Adt(a_d, a_s), Adt(b_d, b_s)) => a_d == b_d && a_s == b_s, + (Foreign(a_d), Foreign(b_d)) => a_d == b_d, + (Array(a_t, a_c), Array(b_t, b_c)) => a_t == b_t && a_c == b_c, + (Slice(a_t), Slice(b_t)) => a_t == b_t, + (RawPtr(a_t), RawPtr(b_t)) => a_t == b_t, + (Ref(a_r, a_t, a_m), Ref(b_r, b_t, b_m)) => a_r == b_r && a_t == b_t && a_m == b_m, + (FnDef(a_d, a_s), FnDef(b_d, b_s)) => a_d == b_d && a_s == b_s, + (FnPtr(a_s), FnPtr(b_s)) => a_s == b_s, + (Dynamic(a_p, a_r, a_repr), Dynamic(b_p, b_r, b_repr)) => { + a_p == b_p && a_r == b_r && a_repr == b_repr + } + (Closure(a_d, a_s), Closure(b_d, b_s)) => a_d == b_d && a_s == b_s, + (Generator(a_d, a_s, a_m), Generator(b_d, b_s, b_m)) => { + a_d == b_d && a_s == b_s && a_m == b_m + } + (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g == b_g, + (GeneratorWitnessMIR(a_d, a_s), GeneratorWitnessMIR(b_d, b_s)) => { + a_d == b_d && a_s == b_s } + (Tuple(a_t), Tuple(b_t)) => a_t == b_t, + (Alias(a_i, a_p), Alias(b_i, b_p)) => a_i == b_i && a_p == b_p, + (Param(a_p), Param(b_p)) => a_p == b_p, + (Bound(a_d, a_b), Bound(b_d, b_b)) => a_d == b_d && a_b == b_b, + (Placeholder(a_p), Placeholder(b_p)) => a_p == b_p, + (Infer(a_t), Infer(b_t)) => a_t == b_t, + (Error(a_e), Error(b_e)) => a_e == b_e, + (Bool, Bool) | (Char, Char) | (Str, Str) | (Never, Never) => true, + _ => { + debug_assert!( + tykind_discriminant(self) != tykind_discriminant(other), + "This branch must be unreachable, maybe the match is missing an arm? self = self = {self:?}, other = {other:?}" + ); + false + } + } } } @@ -360,6 +394,13 @@ impl Ord for TyKind { a_d.cmp(b_d).then_with(|| a_s.cmp(b_s).then_with(|| a_m.cmp(b_m))) } (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g.cmp(b_g), + ( + GeneratorWitnessMIR(a_d, a_s), + GeneratorWitnessMIR(b_d, b_s), + ) => match Ord::cmp(a_d, b_d) { + Ordering::Equal => Ord::cmp(a_s, b_s), + cmp => cmp, + }, (Tuple(a_t), Tuple(b_t)) => a_t.cmp(b_t), (Alias(a_i, a_p), Alias(b_i, b_p)) => a_i.cmp(b_i).then_with(|| a_p.cmp(b_p)), (Param(a_p), Param(b_p)) => a_p.cmp(b_p), @@ -369,7 +410,7 @@ impl Ord for TyKind { (Error(a_e), Error(b_e)) => a_e.cmp(b_e), (Bool, Bool) | (Char, Char) | (Str, Str) | (Never, Never) => Ordering::Equal, _ => { - debug_assert!(false, "This branch must be unreachable, maybe the match is missing an arm? self = self = {self:?}, other = {other:?}"); + debug_assert!(false, "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}"); Ordering::Equal } } @@ -421,6 +462,10 @@ impl hash::Hash for TyKind { m.hash(state) } GeneratorWitness(g) => g.hash(state), + GeneratorWitnessMIR(d, s) => { + d.hash(state); + s.hash(state); + } Tuple(t) => t.hash(state), Alias(i, p) => { i.hash(state); @@ -461,6 +506,7 @@ impl fmt::Debug for TyKind { Closure(d, s) => f.debug_tuple_field2_finish("Closure", d, s), Generator(d, s, m) => f.debug_tuple_field3_finish("Generator", d, s, m), GeneratorWitness(g) => f.debug_tuple_field1_finish("GeneratorWitness", g), + GeneratorWitnessMIR(d, s) => f.debug_tuple_field2_finish("GeneratorWitnessMIR", d, s), Never => f.write_str("Never"), Tuple(t) => f.debug_tuple_field1_finish("Tuple", t), Alias(i, a) => f.debug_tuple_field2_finish("Alias", i, a), @@ -559,6 +605,10 @@ where GeneratorWitness(b) => e.emit_enum_variant(disc, |e| { b.encode(e); }), + GeneratorWitnessMIR(def_id, substs) => e.emit_enum_variant(disc, |e| { + def_id.encode(e); + substs.encode(e); + }), Never => e.emit_enum_variant(disc, |_| {}), Tuple(substs) => e.emit_enum_variant(disc, |e| { substs.encode(e); @@ -641,6 +691,7 @@ where 23 => Placeholder(Decodable::decode(d)), 24 => Infer(Decodable::decode(d)), 25 => Error(Decodable::decode(d)), + 26 => GeneratorWitnessMIR(Decodable::decode(d), Decodable::decode(d)), _ => panic!( "{}", format!( @@ -742,6 +793,10 @@ where GeneratorWitness(b) => { b.hash_stable(__hcx, __hasher); } + GeneratorWitnessMIR(def_id, substs) => { + def_id.hash_stable(__hcx, __hasher); + substs.hash_stable(__hcx, __hasher); + } Never => {} Tuple(substs) => { substs.hash_stable(__hcx, __hasher); @@ -903,6 +958,9 @@ pub enum RegionKind { /// Erased region, used by trait selection, in MIR and during codegen. ReErased, + + /// A region that resulted from some other error. Used exclusively for diagnostics. + ReError(I::ErrorGuaranteed), } // This is manually implemented for `RegionKind` because `std::mem::discriminant` @@ -917,6 +975,7 @@ const fn regionkind_discriminant(value: &RegionKind) -> usize { ReVar(_) => 4, RePlaceholder(_) => 5, ReErased => 6, + ReError(_) => 7, } } @@ -928,6 +987,7 @@ where I::FreeRegion: Copy, I::RegionVid: Copy, I::PlaceholderRegion: Copy, + I::ErrorGuaranteed: Copy, { } @@ -942,6 +1002,7 @@ impl Clone for RegionKind { ReVar(r) => ReVar(r.clone()), RePlaceholder(r) => RePlaceholder(r.clone()), ReErased => ReErased, + ReError(r) => ReError(r.clone()), } } } @@ -959,10 +1020,11 @@ impl PartialEq for RegionKind { (ReVar(a_r), ReVar(b_r)) => a_r == b_r, (RePlaceholder(a_r), RePlaceholder(b_r)) => a_r == b_r, (ReErased, ReErased) => true, + (ReError(_), ReError(_)) => true, _ => { debug_assert!( false, - "This branch must be unreachable, maybe the match is missing an arm? self = self = {self:?}, other = {other:?}" + "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}" ); true } @@ -1020,6 +1082,7 @@ impl hash::Hash for RegionKind { ReVar(r) => r.hash(state), RePlaceholder(r) => r.hash(state), ReErased => (), + ReError(_) => (), } } } @@ -1043,6 +1106,8 @@ impl fmt::Debug for RegionKind { RePlaceholder(placeholder) => write!(f, "RePlaceholder({placeholder:?})"), ReErased => f.write_str("ReErased"), + + ReError(_) => f.write_str("ReError"), } } } @@ -1077,6 +1142,7 @@ where a.encode(e); }), ReErased => e.emit_enum_variant(disc, |_| {}), + ReError(_) => e.emit_enum_variant(disc, |_| {}), } } } @@ -1089,6 +1155,7 @@ where I::FreeRegion: Decodable, I::RegionVid: Decodable, I::PlaceholderRegion: Decodable, + I::ErrorGuaranteed: Decodable, { fn decode(d: &mut D) -> Self { match Decoder::read_usize(d) { @@ -1099,6 +1166,7 @@ where 4 => ReVar(Decodable::decode(d)), 5 => RePlaceholder(Decodable::decode(d)), 6 => ReErased, + 7 => ReError(Decodable::decode(d)), _ => panic!( "{}", format!( @@ -1127,7 +1195,7 @@ where ) { std::mem::discriminant(self).hash_stable(hcx, hasher); match self { - ReErased | ReStatic => { + ReErased | ReStatic | ReError(_) => { // No variant fields to hash for these ... } ReLateBound(d, r) => { -- cgit v1.2.3