Skip to content

Commit a76946b

Browse files
committed
Auto merge of #640 - matthewjasper:anti-canonical, r=jackh726
Replace bound lifetime variables with inference variables in AntiUnifier This fixes an issue that caused an ICE in rust-lang/rust#78502 r? `@jackh726`
2 parents 70e77f1 + 08ad8fd commit a76946b

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

chalk-engine/src/slg/aggregate.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ fn is_trivial<I: Interner>(interner: &I, subst: &Canonical<Substitution<I>>) ->
221221
/// example `Vec<u32>` anti-unified with `Vec<i32>` might be
222222
/// `Vec<?X>`. This is a **very simplistic** anti-unifier.
223223
///
224+
/// NOTE: The values here are canonicalized, but output is not, this means
225+
/// that any escaping bound variables that we see have to be replaced with
226+
/// inference variables.
227+
///
224228
/// [Anti-unification]: https://en.wikipedia.org/wiki/Anti-unification_(computer_science)
225229
struct AntiUnifier<'infer, 'intern, I: Interner> {
226230
infer: &'infer mut InferenceTable<I>,
@@ -243,6 +247,8 @@ impl<I: Interner> AntiUnifier<'_, '_, I> {
243247
// &'a u32)` and `for<'a, 'b> fn(&'a u32, &'b u32)` seems
244248
// kinda hard. Don't try to be smart for now, just plop a
245249
// variable in there and be done with it.
250+
// This also ensures that any bound variables we do see
251+
// were bound by `Canonical`.
246252
(TyKind::BoundVar(_), TyKind::BoundVar(_))
247253
| (TyKind::Function(_), TyKind::Function(_))
248254
| (TyKind::Dyn(_), TyKind::Dyn(_)) => self.new_ty_variable(),
@@ -485,7 +491,12 @@ impl<I: Interner> AntiUnifier<'_, '_, I> {
485491
fn aggregate_lifetimes(&mut self, l1: &Lifetime<I>, l2: &Lifetime<I>) -> Lifetime<I> {
486492
let interner = self.interner;
487493
match (l1.data(interner), l2.data(interner)) {
488-
(LifetimeData::Phantom(..), _) | (_, LifetimeData::Phantom(..)) => unreachable!(),
494+
(LifetimeData::Phantom(void, ..), _) | (_, LifetimeData::Phantom(void, ..)) => {
495+
match *void {}
496+
}
497+
(LifetimeData::BoundVar(..), _) | (_, LifetimeData::BoundVar(..)) => {
498+
self.new_lifetime_variable()
499+
}
489500
_ => {
490501
if l1 == l2 {
491502
l1.clone()

tests/test/numerics.rs

+23
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,26 @@ fn ambiguous_add() {
248248
}
249249
}
250250
}
251+
252+
/// Simplified version of a goal that needs to be solved for type checking
253+
/// `1 << &2`.
254+
#[test]
255+
fn shl_ice() {
256+
test! {
257+
program {
258+
//#[non_enumerable]
259+
trait Shl<Rhs> { }
260+
261+
impl<'a> Shl<&'a u32> for u32 { }
262+
impl<'a> Shl<&'a u16> for u32 { }
263+
}
264+
265+
goal {
266+
exists<U> {
267+
u32: Shl<U>
268+
}
269+
} yields {
270+
"Ambiguous"
271+
}
272+
}
273+
}

0 commit comments

Comments
 (0)