@@ -153,10 +153,11 @@ struct Generalizer<'me, 'tcx, D> {
153153
154154 cache : SsoHashMap < Ty < ' tcx > , Ty < ' tcx > > ,
155155
156- /// This is set once we're generalizing the arguments of an alias. In case
157- /// we encounter an occurs check failure we generalize the alias to an
158- /// inference variable instead of erroring. This is necessary to avoid
159- /// incorrect errors when relating `?0` with `<?0 as Trait>::Assoc`.
156+ /// This is set once we're generalizing the arguments of an alias.
157+ ///
158+ /// This is necessary to correctly handle
159+ /// `<T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0`. This equality can
160+ /// hold by either normalizing the outer or the inner associated type.
160161 in_alias : bool ,
161162
162163 /// See the field `needs_wf` in `Generalization`.
@@ -330,6 +331,12 @@ where
330331 }
331332
332333 ty:: Alias ( kind, data) => {
334+ // An occurs check failure inside of an alias does not mean
335+ // that the types definitely don't unify. We may be able
336+ // to normalize the alias after all.
337+ //
338+ // We handle this by lazily equating the alias and generalizing
339+ // it to an inference variable.
333340 let is_nested_alias = mem:: replace ( & mut self . in_alias , true ) ;
334341 let result = match self . relate ( data, data) {
335342 Ok ( data) => Ok ( Ty :: new_alias ( self . tcx ( ) , kind, data) ) ,
0 commit comments