comment
This commit is contained in:
parent
c0889a6005
commit
49be827dca
1 changed files with 23 additions and 11 deletions
|
@ -1834,6 +1834,27 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
|
||||||
debug!(?late_bound);
|
debug!(?late_bound);
|
||||||
return Some(tcx.arena.alloc(late_bound));
|
return Some(tcx.arena.alloc(late_bound));
|
||||||
|
|
||||||
|
/// Visits a `ty::Ty` collecting information about what generic parameters are constrained.
|
||||||
|
///
|
||||||
|
/// The visitor does not operate on `hir::Ty` so that it can be called on the rhs of a `type Alias<...> = ...;`
|
||||||
|
/// which may live in a separate crate so there would not be any hir available. Instead we use the `type_of`
|
||||||
|
/// query to obtain a `ty::Ty` which will be present even in cross crate scenarios. It also naturally
|
||||||
|
/// handles cycle detection as we go through the query system.
|
||||||
|
///
|
||||||
|
/// This is necessary in the first place for the following case:
|
||||||
|
/// ```
|
||||||
|
/// type Alias<'a, T> = <T as Trait<'a>>::Assoc;
|
||||||
|
/// fn foo<'a>(_: Alias<'a, ()>) -> Alias<'a, ()> { ... }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If we conservatively considered `'a` unconstrained then we could break users who had written code before
|
||||||
|
/// we started correctly handling aliases. If we considered `'a` constrained then it would become late bound
|
||||||
|
/// causing an error during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
|
||||||
|
/// but appears in the output type `<() as Trait<'a>>::Assoc`.
|
||||||
|
///
|
||||||
|
/// We must therefore "look into" the `Alias` to see whether we should consider `'a` constrained or not.
|
||||||
|
///
|
||||||
|
/// See #100508 #85533 #47511 for additional context
|
||||||
struct ConstrainedCollectorPostAstConv {
|
struct ConstrainedCollectorPostAstConv {
|
||||||
arg_is_constrained: Box<[bool]>,
|
arg_is_constrained: Box<[bool]>,
|
||||||
}
|
}
|
||||||
|
@ -1886,17 +1907,8 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
|
||||||
None,
|
None,
|
||||||
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
|
hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
|
||||||
)) => {
|
)) => {
|
||||||
// If this is a top level type alias attempt to "look through" it to see if the args
|
// See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
|
||||||
// are constrained, instead of assuming they are and inserting all the lifetimes.
|
// substs to be unconstrained.
|
||||||
// This is necessary for the following case:
|
|
||||||
// ```
|
|
||||||
// type Alias<'a, T> = <T as Trait<'a>>::Assoc;
|
|
||||||
// fn foo<'a>(_: Alias<'a, ()>) -> Alias<'a, ()> { ... }
|
|
||||||
// ```
|
|
||||||
// If we considered `'a` constrained then it would become late bound causing an error
|
|
||||||
// during astconv as the `'a` is not constrained by the input type `<() as Trait<'a>>::Assoc`
|
|
||||||
// but appears in the output type `<() as Trait<'a>>::Assoc`.
|
|
||||||
|
|
||||||
let generics = self.tcx.generics_of(alias_def);
|
let generics = self.tcx.generics_of(alias_def);
|
||||||
let mut walker = ConstrainedCollectorPostAstConv {
|
let mut walker = ConstrainedCollectorPostAstConv {
|
||||||
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
|
arg_is_constrained: vec![false; generics.params.len()].into_boxed_slice(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue