Skip to content

Commit 8810af8

Browse files
authored
Rollup merge of #93227 - compiler-errors:gat-hrtb-wfcheck, r=jackh726
Liberate late bound regions when collecting GAT substs in wfcheck The issue here is that the [`GATSubstCollector`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_typeck/src/check/wfcheck.rs#L604) does not currently do anything wrt `Binder`s, so the GAT substs it copies out have escaping late bound regions when it walks through types like `for<'x> fn() -> Self::Gat<'x>`. I made that visitor call `liberate_late_bound_regions`, not sure if that's the right thing here or we need to do something else to replace these bound vars with placeholders. I'm not familiar with other code doing anything similar.. But the issue is indeed no longer ICEing. Fixes #92954 r? `@jackh726` since you last touched this code, feel free to reassign
2 parents 5adef28 + 4a74ace commit 8810af8

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

compiler/rustc_typeck/src/check/wfcheck.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ fn check_gat_where_clauses(
312312
// of the function signature. In our example, the GAT in the return
313313
// type is `<Self as LendingIterator>::Item<'a>`, so 'a and Self are arguments.
314314
let (regions, types) =
315-
GATSubstCollector::visit(trait_item.def_id.to_def_id(), sig.output());
315+
GATSubstCollector::visit(tcx, trait_item.def_id.to_def_id(), sig.output());
316316

317317
// If both regions and types are empty, then this GAT isn't in the
318318
// return type, and we shouldn't try to do clause analysis
@@ -602,6 +602,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
602602
/// the two vectors, `regions` and `types` (depending on their kind). For each
603603
/// parameter `Pi` also track the index `i`.
604604
struct GATSubstCollector<'tcx> {
605+
tcx: TyCtxt<'tcx>,
605606
gat: DefId,
606607
// Which region appears and which parameter index its subsituted for
607608
regions: FxHashSet<(ty::Region<'tcx>, usize)>,
@@ -611,11 +612,16 @@ struct GATSubstCollector<'tcx> {
611612

612613
impl<'tcx> GATSubstCollector<'tcx> {
613614
fn visit<T: TypeFoldable<'tcx>>(
615+
tcx: TyCtxt<'tcx>,
614616
gat: DefId,
615617
t: T,
616618
) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
617-
let mut visitor =
618-
GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() };
619+
let mut visitor = GATSubstCollector {
620+
tcx,
621+
gat,
622+
regions: FxHashSet::default(),
623+
types: FxHashSet::default(),
624+
};
619625
t.visit_with(&mut visitor);
620626
(visitor.regions, visitor.types)
621627
}
@@ -624,6 +630,13 @@ impl<'tcx> GATSubstCollector<'tcx> {
624630
impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
625631
type BreakTy = !;
626632

633+
fn visit_binder<T: TypeFoldable<'tcx>>(
634+
&mut self,
635+
t: &ty::Binder<'tcx, T>,
636+
) -> ControlFlow<Self::BreakTy> {
637+
self.tcx.liberate_late_bound_regions(self.gat, t.clone()).visit_with(self)
638+
}
639+
627640
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
628641
match t.kind() {
629642
ty::Projection(p) if p.item_def_id == self.gat => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// check-pass
2+
3+
#![feature(generic_associated_types)]
4+
5+
pub trait Foo {
6+
type Assoc<'c>;
7+
fn function() -> for<'x> fn(Self::Assoc<'x>);
8+
}
9+
10+
fn main() {}

0 commit comments

Comments
 (0)