mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
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
This commit is contained in:
commit
8810af8082
@ -312,7 +312,7 @@ fn check_gat_where_clauses(
|
||||
// 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.
|
||||
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
|
||||
// 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
|
||||
/// parameter `Pi` also track the index `i`.
|
||||
struct GATSubstCollector<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
gat: DefId,
|
||||
// Which region appears and which parameter index its subsituted for
|
||||
regions: FxHashSet<(ty::Region<'tcx>, usize)>,
|
||||
@ -611,11 +612,16 @@ struct GATSubstCollector<'tcx> {
|
||||
|
||||
impl<'tcx> GATSubstCollector<'tcx> {
|
||||
fn visit<T: TypeFoldable<'tcx>>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
gat: DefId,
|
||||
t: T,
|
||||
) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
|
||||
let mut visitor =
|
||||
GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() };
|
||||
let mut visitor = GATSubstCollector {
|
||||
tcx,
|
||||
gat,
|
||||
regions: FxHashSet::default(),
|
||||
types: FxHashSet::default(),
|
||||
};
|
||||
t.visit_with(&mut visitor);
|
||||
(visitor.regions, visitor.types)
|
||||
}
|
||||
@ -624,6 +630,13 @@ impl<'tcx> GATSubstCollector<'tcx> {
|
||||
impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
|
||||
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> {
|
||||
match t.kind() {
|
||||
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…
Reference in New Issue
Block a user