Skip to content

Commit f3b3156

Browse files
committed
Fix "var_universe invoked on bound variable" crash
This should fix rust-lang/rust-analyzer#5495. `unify_ty_ty` calls `normalize_ty_shallow` on both types and then assumes that they can't be bound variables. With integer type variables, this assumption was broken, because you could have a general type variable resolving to an integer type variable resolving to i32. To fix this, `normalize_ty_shallow` probes twice, to make sure to fully resolve the variable.
1 parent f2e3fd9 commit f3b3156

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

chalk-solve/src/infer.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ impl<I: Interner> InferenceTable<I> {
119119
}
120120

121121
pub fn normalize_ty_shallow(&mut self, interner: &I, leaf: &Ty<I>) -> Option<Ty<I>> {
122+
// An integer/float type variable will never normalize to another
123+
// variable; but a general type variable might normalize to an
124+
// integer/float variable. So we potentially need to normalize twice to
125+
// get at the actual value.
126+
self.normalize_ty_shallow_inner(interner, leaf)
127+
.map(|ty| self.normalize_ty_shallow_inner(interner, &ty).unwrap_or(ty))
128+
}
129+
130+
fn normalize_ty_shallow_inner(&mut self, interner: &I, leaf: &Ty<I>) -> Option<Ty<I>> {
122131
self.probe_var(leaf.inference_var(interner)?)
123132
.map(|p| p.assert_ty_ref(interner).clone())
124133
}

tests/test/numerics.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,26 @@ fn shl_ice() {
271271
}
272272
}
273273
}
274+
275+
/// Regression test for rust-analyzer#5495 ("var_universe invoked on bound
276+
/// variable" crash).
277+
#[test]
278+
fn unify_general_then_specific_ty() {
279+
test! {
280+
program {
281+
#[non_enumerable]
282+
trait Foo {}
283+
struct Bar<T> {}
284+
285+
impl<T> Foo for Bar<(T, T, i32, i32)> {}
286+
}
287+
288+
goal {
289+
exists<T, int N> {
290+
Bar<(N, T, T, T)>: Foo
291+
}
292+
} yields {
293+
"Unique"
294+
}
295+
}
296+
}

0 commit comments

Comments
 (0)