diff options
| author | bors <bors@rust-lang.org> | 2023-08-31 21:13:54 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-08-31 21:13:54 +0000 |
| commit | 2f5df8a94bb3c5fae4e3fcbfc8ef20f1f976cb19 (patch) | |
| tree | 2debe88f71298af364acbe602491b59c32732950 | |
| parent | 91942134c67bf43ee007351c2a8e378b95623b2e (diff) | |
| parent | f1679f7dd6330535cd2dbd0dd18ded0dc8a7e6d9 (diff) | |
| download | rust-2f5df8a94bb3c5fae4e3fcbfc8ef20f1f976cb19.tar.gz rust-2f5df8a94bb3c5fae4e3fcbfc8ef20f1f976cb19.zip | |
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
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 1 | ||||
| -rw-r--r-- | tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs | 19 |
3 files changed, 31 insertions, 0 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a4ba1a5c9bf..a6d1ef33f40 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -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 @@ impl ResolverAstLoweringExt for ResolverAstLowering { 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 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // 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(); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 500004269c9..fa04a594555 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1109,6 +1109,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, } }, AssocConstraintKind::Bound { ref bounds } => { + self.record_lifetime_params_for_impl_trait(constraint.id); walk_list!(self, visit_param_bound, bounds, BoundKind::Bound); } } diff --git a/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs new file mode 100644 index 00000000000..49d36d6c99c --- /dev/null +++ b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs @@ -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() {} |
