@@ -1834,6 +1834,27 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
18341834 debug ! ( ?late_bound) ;
18351835 return Some ( tcx. arena . alloc ( late_bound) ) ;
18361836
1837+ /// Visits a `ty::Ty` collecting information about what generic parameters are constrained.
1838+ ///
1839+ /// The visitor does not operate on `hir::Ty` so that it can be called on the rhs of a `type Alias<...> = ...;`
1840+ /// which may live in a separate crate so there would not be any hir available. Instead we use the `type_of`
1841+ /// query to obtain a `ty::Ty` which will be present even in cross crate scenarios. It also naturally
1842+ /// handles cycle detection as we go through the query system.
1843+ ///
1844+ /// This is necessary in the first place for the following case:
1845+ /// ```
1846+ /// type Alias<'a, T> = <T as Trait<'a>>::Assoc;
1847+ /// fn foo<'a>(_: Alias<'a, ()>) -> Alias<'a, ()> { ... }
1848+ /// ```
1849+ ///
1850+ /// If we conservatively considered `'a` unconstrained then we could break users who had written code before
1851+ /// we started correctly handling aliases. If we considered `'a` constrained then it would become late bound
1852+ /// causing an error during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
1853+ /// but appears in the output type `<() as Trait<'a>>::Assoc`.
1854+ ///
1855+ /// We must therefore "look into" the `Alias` to see whether we should consider `'a` constrained or not.
1856+ ///
1857+ /// See #100508 #85533 #47511 for additional context
18371858 struct ConstrainedCollectorPostAstConv {
18381859 arg_is_constrained : Box < [ bool ] > ,
18391860 }
@@ -1886,17 +1907,8 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
18861907 None ,
18871908 hir:: Path { res : Res :: Def ( DefKind :: TyAlias , alias_def) , segments, span } ,
18881909 ) ) => {
1889- // If this is a top level type alias attempt to "look through" it to see if the args
1890- // are constrained, instead of assuming they are and inserting all the lifetimes.
1891- // This is necessary for the following case:
1892- // ```
1893- // type Alias<'a, T> = <T as Trait<'a>>::Assoc;
1894- // fn foo<'a>(_: Alias<'a, ()>) -> Alias<'a, ()> { ... }
1895- // ```
1896- // If we considered `'a` constrained then it would become late bound causing an error
1897- // during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
1898- // but appears in the output type `<() as Trait<'a>>::Assoc`.
1899-
1910+ // See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
1911+ // substs to be unconstrained.
19001912 let generics = self . tcx . generics_of ( alias_def) ;
19011913 let mut walker = ConstrainedCollectorPostAstConv {
19021914 arg_is_constrained : vec ! [ false ; generics. params. len( ) ] . into_boxed_slice ( ) ,
0 commit comments