summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_type_ir/src/sty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_type_ir/src/sty.rs')
-rw-r--r--compiler/rustc_type_ir/src/sty.rs156
1 files changed, 112 insertions, 44 deletions
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<T>`, `Rc<T>`, etc.
DynStar,
}
@@ -160,6 +158,32 @@ pub enum TyKind<I: Interner> {
/// ```
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<i32>, &'a Vec<i32>]`:
+ ///
+ /// ```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<I: Interner>(value: &TyKind<I>) -> usize {
Placeholder(_) => 23,
Infer(_) => 24,
Error(_) => 25,
+ GeneratorWitnessMIR(_, _) => 26,
}
}
@@ -266,6 +291,7 @@ impl<I: Interner> Clone for TyKind<I> {
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<I: Interner> Clone for TyKind<I> {
impl<I: Interner> PartialEq for TyKind<I> {
#[inline]
fn eq(&self, other: &TyKind<I>) -> 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<I: Interner> Ord for TyKind<I> {
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<I: Interner> Ord for TyKind<I> {
(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<I: Interner> hash::Hash for TyKind<I> {
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<I: Interner> fmt::Debug for TyKind<I> {
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<I: Interner> {
/// 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<I: Interner>(value: &RegionKind<I>) -> 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<I: Interner> Clone for RegionKind<I> {
ReVar(r) => ReVar(r.clone()),
RePlaceholder(r) => RePlaceholder(r.clone()),
ReErased => ReErased,
+ ReError(r) => ReError(r.clone()),
}
}
}
@@ -959,10 +1020,11 @@ impl<I: Interner> PartialEq for RegionKind<I> {
(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<I: Interner> hash::Hash for RegionKind<I> {
ReVar(r) => r.hash(state),
RePlaceholder(r) => r.hash(state),
ReErased => (),
+ ReError(_) => (),
}
}
}
@@ -1043,6 +1106,8 @@ impl<I: Interner> fmt::Debug for RegionKind<I> {
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<D>,
I::RegionVid: Decodable<D>,
I::PlaceholderRegion: Decodable<D>,
+ I::ErrorGuaranteed: Decodable<D>,
{
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) => {