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

This commit is contained in:
Michael Goulet 2023-08-29 23:47:01 +00:00
parent b2515fa741
commit f1679f7dd6
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() {}