@@ -221,6 +221,10 @@ fn is_trivial<I: Interner>(interner: &I, subst: &Canonical<Substitution<I>>) ->
221
221
/// example `Vec<u32>` anti-unified with `Vec<i32>` might be
222
222
/// `Vec<?X>`. This is a **very simplistic** anti-unifier.
223
223
///
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
+ ///
224
228
/// [Anti-unification]: https://en.wikipedia.org/wiki/Anti-unification_(computer_science)
225
229
struct AntiUnifier < ' infer , ' intern , I : Interner > {
226
230
infer : & ' infer mut InferenceTable < I > ,
@@ -243,6 +247,8 @@ impl<I: Interner> AntiUnifier<'_, '_, I> {
243
247
// &'a u32)` and `for<'a, 'b> fn(&'a u32, &'b u32)` seems
244
248
// kinda hard. Don't try to be smart for now, just plop a
245
249
// variable in there and be done with it.
250
+ // This also ensures that any bound variables we do see
251
+ // were bound by `Canonical`.
246
252
( TyKind :: BoundVar ( _) , TyKind :: BoundVar ( _) )
247
253
| ( TyKind :: Function ( _) , TyKind :: Function ( _) )
248
254
| ( TyKind :: Dyn ( _) , TyKind :: Dyn ( _) ) => self . new_ty_variable ( ) ,
@@ -485,7 +491,12 @@ impl<I: Interner> AntiUnifier<'_, '_, I> {
485
491
fn aggregate_lifetimes ( & mut self , l1 : & Lifetime < I > , l2 : & Lifetime < I > ) -> Lifetime < I > {
486
492
let interner = self . interner ;
487
493
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
+ }
489
500
_ => {
490
501
if l1 == l2 {
491
502
l1. clone ( )
0 commit comments