@@ -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)
225229struct 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 ( )
0 commit comments