Liberate late bound regions when collecting GAT substs in wfcheck
This commit is contained in:
parent
10c4c4afec
commit
4a74ace3c9
@ -312,7 +312,7 @@ fn check_gat_where_clauses(
|
|||||||
// of the function signature. In our example, the GAT in the return
|
// of the function signature. In our example, the GAT in the return
|
||||||
// type is `<Self as LendingIterator>::Item<'a>`, so 'a and Self are arguments.
|
// type is `<Self as LendingIterator>::Item<'a>`, so 'a and Self are arguments.
|
||||||
let (regions, types) =
|
let (regions, types) =
|
||||||
GATSubstCollector::visit(trait_item.def_id.to_def_id(), sig.output());
|
GATSubstCollector::visit(tcx, trait_item.def_id.to_def_id(), sig.output());
|
||||||
|
|
||||||
// If both regions and types are empty, then this GAT isn't in the
|
// If both regions and types are empty, then this GAT isn't in the
|
||||||
// return type, and we shouldn't try to do clause analysis
|
// return type, and we shouldn't try to do clause analysis
|
||||||
@ -602,6 +602,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
|
|||||||
/// the two vectors, `regions` and `types` (depending on their kind). For each
|
/// the two vectors, `regions` and `types` (depending on their kind). For each
|
||||||
/// parameter `Pi` also track the index `i`.
|
/// parameter `Pi` also track the index `i`.
|
||||||
struct GATSubstCollector<'tcx> {
|
struct GATSubstCollector<'tcx> {
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
gat: DefId,
|
gat: DefId,
|
||||||
// Which region appears and which parameter index its subsituted for
|
// Which region appears and which parameter index its subsituted for
|
||||||
regions: FxHashSet<(ty::Region<'tcx>, usize)>,
|
regions: FxHashSet<(ty::Region<'tcx>, usize)>,
|
||||||
@ -611,11 +612,16 @@ struct GATSubstCollector<'tcx> {
|
|||||||
|
|
||||||
impl<'tcx> GATSubstCollector<'tcx> {
|
impl<'tcx> GATSubstCollector<'tcx> {
|
||||||
fn visit<T: TypeFoldable<'tcx>>(
|
fn visit<T: TypeFoldable<'tcx>>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
gat: DefId,
|
gat: DefId,
|
||||||
t: T,
|
t: T,
|
||||||
) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
|
) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
|
||||||
let mut visitor =
|
let mut visitor = GATSubstCollector {
|
||||||
GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() };
|
tcx,
|
||||||
|
gat,
|
||||||
|
regions: FxHashSet::default(),
|
||||||
|
types: FxHashSet::default(),
|
||||||
|
};
|
||||||
t.visit_with(&mut visitor);
|
t.visit_with(&mut visitor);
|
||||||
(visitor.regions, visitor.types)
|
(visitor.regions, visitor.types)
|
||||||
}
|
}
|
||||||
@ -624,6 +630,13 @@ impl<'tcx> GATSubstCollector<'tcx> {
|
|||||||
impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
|
impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
|
||||||
type BreakTy = !;
|
type BreakTy = !;
|
||||||
|
|
||||||
|
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||||
|
&mut self,
|
||||||
|
t: &ty::Binder<'tcx, T>,
|
||||||
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
|
self.tcx.liberate_late_bound_regions(self.gat, t.clone()).visit_with(self)
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::Projection(p) if p.item_def_id == self.gat => {
|
ty::Projection(p) if p.item_def_id == self.gat => {
|
||||||
|
10
src/test/ui/generic-associated-types/issue-92954.rs
Normal file
10
src/test/ui/generic-associated-types/issue-92954.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(generic_associated_types)]
|
||||||
|
|
||||||
|
pub trait Foo {
|
||||||
|
type Assoc<'c>;
|
||||||
|
fn function() -> for<'x> fn(Self::Assoc<'x>);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user