diff --git a/chalk-engine/src/slg/resolvent.rs b/chalk-engine/src/slg/resolvent.rs index 35cc0241910..8606026006a 100644 --- a/chalk-engine/src/slg/resolvent.rs +++ b/chalk-engine/src/slg/resolvent.rs @@ -627,7 +627,8 @@ impl<'i, I: Interner> Zipper for AnswerSubstitutor<'i, I> { (LifetimeData::Static, _) | (LifetimeData::BoundVar(_), _) | (LifetimeData::Placeholder(_), _) - | (LifetimeData::Erased, _) => panic!( + | (LifetimeData::Erased, _) + | (LifetimeData::Error, _) => panic!( "structural mismatch between answer `{:?}` and pending goal `{:?}`", answer, pending, ), diff --git a/chalk-ir/src/debug.rs b/chalk-ir/src/debug.rs index aac1fa35741..8aa48d7de25 100644 --- a/chalk-ir/src/debug.rs +++ b/chalk-ir/src/debug.rs @@ -307,6 +307,7 @@ impl Debug for LifetimeData { LifetimeData::Placeholder(index) => write!(fmt, "'{:?}", index), LifetimeData::Static => write!(fmt, "'static"), LifetimeData::Erased => write!(fmt, "'"), + LifetimeData::Error => write!(fmt, "'{{error}}"), LifetimeData::Phantom(..) => unreachable!(), } } diff --git a/chalk-ir/src/fold.rs b/chalk-ir/src/fold.rs index 3b4531b1ee1..d0524db6541 100644 --- a/chalk-ir/src/fold.rs +++ b/chalk-ir/src/fold.rs @@ -822,6 +822,7 @@ where } LifetimeData::Static => Ok(LifetimeData::::Static.intern(folder.interner())), LifetimeData::Erased => Ok(LifetimeData::::Erased.intern(folder.interner())), + LifetimeData::Error => Ok(LifetimeData::::Error.intern(folder.interner())), LifetimeData::Phantom(void, ..) => match *void {}, } } diff --git a/chalk-ir/src/lib.rs b/chalk-ir/src/lib.rs index 70c4f4cc5aa..4a765673afc 100644 --- a/chalk-ir/src/lib.rs +++ b/chalk-ir/src/lib.rs @@ -555,14 +555,16 @@ bitflags! { const HAS_CT_PROJECTION = 1 << 9; /// Does the type contain an error const HAS_ERROR = 1 << 10; + /// Does the type contain an error lifetime + const HAS_RE_ERROR = 1 << 11; /// Does the type contain any free lifetimes - const HAS_FREE_REGIONS = 1 << 11; + const HAS_FREE_REGIONS = 1 << 12; /// True when the type contains lifetimes that will be substituted when function is called - const HAS_RE_LATE_BOUND = 1 << 12; + const HAS_RE_LATE_BOUND = 1 << 13; /// True when the type contains an erased lifetime - const HAS_RE_ERASED = 1 << 13; + const HAS_RE_ERASED = 1 << 14; /// Does the type contain placeholders or inference variables that could be replaced later - const STILL_FURTHER_SPECIALIZABLE = 1 << 14; + const STILL_FURTHER_SPECIALIZABLE = 1 << 15; /// True when the type contains free names local to a particular context const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_INFER.bits() @@ -1280,6 +1282,7 @@ impl Lifetime { LifetimeData::Placeholder(_) => false, LifetimeData::Static => false, LifetimeData::Erased => false, + LifetimeData::Error => false, LifetimeData::Phantom(..) => unreachable!(), } } @@ -1301,6 +1304,7 @@ impl Lifetime { LifetimeData::Phantom(_, _) => TypeFlags::empty(), LifetimeData::BoundVar(_) => TypeFlags::HAS_RE_LATE_BOUND, LifetimeData::Erased => TypeFlags::HAS_RE_ERASED, + LifetimeData::Error => TypeFlags::HAS_RE_ERROR, } } } @@ -1321,6 +1325,8 @@ pub enum LifetimeData { Erased, /// Lifetime on phantom data. Phantom(Void, PhantomData), + /// A lifetime that resulted from some error + Error, } impl LifetimeData { diff --git a/chalk-ir/src/visit.rs b/chalk-ir/src/visit.rs index 2dee118100d..e72ea1e6f02 100644 --- a/chalk-ir/src/visit.rs +++ b/chalk-ir/src/visit.rs @@ -330,7 +330,9 @@ impl TypeSuperVisitable for Lifetime { LifetimeData::Placeholder(universe) => { visitor.visit_free_placeholder(*universe, outer_binder) } - LifetimeData::Static | LifetimeData::Erased => ControlFlow::Continue(()), + LifetimeData::Static | LifetimeData::Erased | LifetimeData::Error => { + ControlFlow::Continue(()) + } LifetimeData::Phantom(void, ..) => match *void {}, } } diff --git a/chalk-solve/src/display/ty.rs b/chalk-solve/src/display/ty.rs index e3402bf67bc..a00be4d8719 100644 --- a/chalk-solve/src/display/ty.rs +++ b/chalk-solve/src/display/ty.rs @@ -241,6 +241,7 @@ impl RenderAsRust for LifetimeData { } LifetimeData::Static => write!(f, "'static"), LifetimeData::Erased => write!(f, "'_"), + LifetimeData::Error => write!(f, "'{{error}}"), // Matching the void ensures at compile time that this code is // unreachable LifetimeData::Phantom(void, _) => match *void {}, diff --git a/chalk-solve/src/infer/unify.rs b/chalk-solve/src/infer/unify.rs index e4b4d5a152c..1ce4796da98 100644 --- a/chalk-solve/src/infer/unify.rs +++ b/chalk-solve/src/infer/unify.rs @@ -963,12 +963,14 @@ impl<'t, I: Interner> Unifier<'t, I> { ) => self.unify_lifetime_var(variance.invert(), b_var, a, ui), (&LifetimeData::InferenceVar(a_var), &LifetimeData::Erased) - | (&LifetimeData::InferenceVar(a_var), &LifetimeData::Static) => { + | (&LifetimeData::InferenceVar(a_var), &LifetimeData::Static) + | (&LifetimeData::InferenceVar(a_var), &LifetimeData::Error) => { self.unify_lifetime_var(variance, a_var, b, UniverseIndex::root()) } (&LifetimeData::Erased, &LifetimeData::InferenceVar(b_var)) - | (&LifetimeData::Static, &LifetimeData::InferenceVar(b_var)) => { + | (&LifetimeData::Static, &LifetimeData::InferenceVar(b_var)) + | (&LifetimeData::Error, &LifetimeData::InferenceVar(b_var)) => { self.unify_lifetime_var(variance.invert(), b_var, a, UniverseIndex::root()) } @@ -990,6 +992,7 @@ impl<'t, I: Interner> Unifier<'t, I> { } } + (LifetimeData::Error, _) | (_, LifetimeData::Error) => Ok(()), (LifetimeData::BoundVar(_), _) | (_, LifetimeData::BoundVar(_)) => panic!( "unification encountered bound variable: a={:?} b={:?}", a, b