@@ -153,10 +153,11 @@ struct Generalizer<'me, 'tcx, D> {
153
153
154
154
cache : SsoHashMap < Ty < ' tcx > , Ty < ' tcx > > ,
155
155
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.
160
161
in_alias : bool ,
161
162
162
163
/// See the field `needs_wf` in `Generalization`.
@@ -330,6 +331,12 @@ where
330
331
}
331
332
332
333
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.
333
340
let is_nested_alias = mem:: replace ( & mut self . in_alias , true ) ;
334
341
let result = match self . relate ( data, data) {
335
342
Ok ( data) => Ok ( Ty :: new_alias ( self . tcx ( ) , kind, data) ) ,
0 commit comments