Auto merge of #115366 - compiler-errors:associated-type-bound-implicit-lifetimes, r=jackh726

Capture lifetimes for associated type bounds destined to be lowered to opaques

Some associated type bounds get lowered to opaques, but they're not represented in the AST as opaques.

That means that we never collect lifetimes for them (`record_lifetime_params_for_impl_trait`) which are used currently for RPITITs, which capture all of their in-scope lifetimes[^1]. This means that the nested RPITITs that arise from some type like `impl Foo<Type: Bar>` (~> `impl Foo<Type = impl Bar>`) don't capture any lifetimes, leading to ICEs.

This PR makes sure we collect the lifetimes for associated type bounds as well, and make sure that they are set up correctly for opaque type lowering later.

Fixes #115360

[^1]: #114489
This commit is contained in:
bors 2023-08-31 21:13:54 +00:00
commit 2f5df8a94b
3 changed files with 31 additions and 0 deletions

View File

@ -153,6 +153,7 @@ trait ResolverAstLoweringExt {
fn get_label_res(&self, id: NodeId) -> Option<NodeId>;
fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>;
fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>;
fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId);
fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind;
}
@ -213,6 +214,11 @@ fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, Life
self.extra_lifetime_params_map.remove(&id).unwrap_or_default()
}
fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId) {
let lifetimes = self.extra_lifetime_params_map.remove(&from).unwrap_or_default();
self.extra_lifetime_params_map.insert(to, lifetimes);
}
fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind {
self.builtin_macro_kinds.get(&def_id).copied().unwrap_or(MacroKind::Bang)
}
@ -1089,6 +1095,11 @@ enum DesugarKind<'a> {
// constructing the HIR for `impl bounds...` and then lowering that.
let impl_trait_node_id = self.next_node_id();
// Shift `impl Trait` lifetime captures from the associated type bound's
// node id to the opaque node id, so that the opaque can actually use
// these lifetime bounds.
self.resolver
.remap_extra_lifetime_params(constraint.id, impl_trait_node_id);
self.with_dyn_type_scope(false, |this| {
let node_id = this.next_node_id();

View File

@ -1109,6 +1109,7 @@ fn visit_assoc_constraint(&mut self, constraint: &'ast AssocConstraint) {
}
},
AssocConstraintKind::Bound { ref bounds } => {
self.record_lifetime_params_for_impl_trait(constraint.id);
walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
}
}

View File

@ -0,0 +1,19 @@
// check-pass
#![feature(associated_type_bounds, return_position_impl_trait_in_trait)]
trait Trait {
type Type;
fn method(&self) -> impl Trait<Type: '_>;
}
impl Trait for () {
type Type = ();
fn method(&self) -> impl Trait<Type: '_> {
()
}
}
fn main() {}