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:
commit
2f5df8a94b
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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() {}
|
Loading…
Reference in New Issue
Block a user