diff options
| author | Michael Goulet <michael@errs.io> | 2023-08-04 23:54:14 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-08-28 01:05:34 +0000 |
| commit | 13d3e57237eefd92a518d99367b6f8e04110e847 (patch) | |
| tree | d06c8225cbc4db213c376f1cdfd1fd84bf1db64a /compiler | |
| parent | 8550f15e148407159af401e02b1d9259762b3496 (diff) | |
| download | rust-13d3e57237eefd92a518d99367b6f8e04110e847.tar.gz rust-13d3e57237eefd92a518d99367b6f8e04110e847.zip | |
RPITITs capture all their lifetimes
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 53 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 21 |
2 files changed, 40 insertions, 34 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1827e42368f..a4ba1a5c9bf 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -236,7 +236,7 @@ enum ImplTraitContext { ReturnPositionOpaqueTy { /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn, origin: hir::OpaqueTyOrigin, - in_trait: bool, + fn_kind: FnDeclKind, }, /// Impl trait in type aliases. TypeAliasesOpaqueTy { in_assoc_ty: bool }, @@ -312,7 +312,7 @@ impl std::fmt::Display for ImplTraitPosition { } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] enum FnDeclKind { Fn, Inherent, @@ -1401,13 +1401,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { TyKind::ImplTrait(def_node_id, bounds) => { let span = t.span; match itctx { - ImplTraitContext::ReturnPositionOpaqueTy { origin, in_trait } => self + ImplTraitContext::ReturnPositionOpaqueTy { origin, fn_kind } => self .lower_opaque_impl_trait( span, *origin, *def_node_id, bounds, - *in_trait, + Some(*fn_kind), itctx, ), &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self @@ -1416,7 +1416,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::OpaqueTyOrigin::TyAlias { in_assoc_ty }, *def_node_id, bounds, - false, + None, itctx, ), ImplTraitContext::Universal => { @@ -1523,7 +1523,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { origin: hir::OpaqueTyOrigin, opaque_ty_node_id: NodeId, bounds: &GenericBounds, - in_trait: bool, + fn_kind: Option<FnDeclKind>, itctx: &ImplTraitContext, ) -> hir::TyKind<'hir> { // Make sure we know that some funky desugaring has been going on here. @@ -1540,10 +1540,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Vec::new() } hir::OpaqueTyOrigin::FnReturn(..) => { - // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` - // example, we only need to duplicate lifetimes that appear in the - // bounds, since those are the only ones that are captured by the opaque. - lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds) + if let FnDeclKind::Impl | FnDeclKind::Trait = + fn_kind.expect("expected RPITs to be lowered with a FnKind") + { + // return-position impl trait in trait was decided to capture all + // in-scope lifetimes, which we collect for all opaques during resolution. + self.resolver + .take_extra_lifetime_params(opaque_ty_node_id) + .into_iter() + .map(|(ident, id, _)| Lifetime { id, ident }) + .collect() + } else { + // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` + // example, we only need to duplicate lifetimes that appear in the + // bounds, since those are the only ones that are captured by the opaque. + lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds) + } } hir::OpaqueTyOrigin::AsyncFn(..) => { unreachable!("should be using `lower_async_fn_ret_ty`") @@ -1554,7 +1566,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_opaque_inner( opaque_ty_node_id, origin, - in_trait, + matches!(fn_kind, Some(FnDeclKind::Trait)), captured_lifetimes_to_duplicate, span, opaque_ty_span, @@ -1802,12 +1814,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } let fn_def_id = self.local_def_id(fn_node_id); - self.lower_async_fn_ret_ty( - &decl.output, - fn_def_id, - ret_id, - matches!(kind, FnDeclKind::Trait), - ) + self.lower_async_fn_ret_ty(&decl.output, fn_def_id, ret_id, kind) } else { match &decl.output { FnRetTy::Ty(ty) => { @@ -1815,7 +1822,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let fn_def_id = self.local_def_id(fn_node_id); ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), - in_trait: matches!(kind, FnDeclKind::Trait), + fn_kind: kind, } } else { let position = match kind { @@ -1883,7 +1890,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { output: &FnRetTy, fn_def_id: LocalDefId, opaque_ty_node_id: NodeId, - in_trait: bool, + fn_kind: FnDeclKind, ) -> hir::FnRetTy<'hir> { let span = self.lower_span(output.span()); let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None); @@ -1898,7 +1905,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_ref = self.lower_opaque_inner( opaque_ty_node_id, hir::OpaqueTyOrigin::AsyncFn(fn_def_id), - in_trait, + matches!(fn_kind, FnDeclKind::Trait), captured_lifetimes, span, opaque_ty_span, @@ -1906,7 +1913,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let future_bound = this.lower_async_fn_output_type_to_future_bound( output, span, - if in_trait && !this.tcx.features().return_position_impl_trait_in_trait { + if let FnDeclKind::Trait = fn_kind + && !this.tcx.features().return_position_impl_trait_in_trait + { ImplTraitContext::FeatureGated( ImplTraitPosition::TraitReturn, sym::return_position_impl_trait_in_trait, @@ -1914,7 +1923,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), - in_trait, + fn_kind, } }, ); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 22d084c8e0b..500004269c9 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -772,9 +772,10 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, self.r.record_partial_res(ty.id, PartialRes::new(res)); visit::walk_ty(self, ty) } - TyKind::ImplTrait(..) => { + TyKind::ImplTrait(node_id, _) => { let candidates = self.lifetime_elision_candidates.take(); visit::walk_ty(self, ty); + self.record_lifetime_params_for_impl_trait(*node_id); self.lifetime_elision_candidates = candidates; } TyKind::TraitObject(bounds, ..) => { @@ -909,8 +910,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, &sig.decl.output, ); - if let Some((async_node_id, span)) = sig.header.asyncness.opt_return_id() { - this.record_lifetime_params_for_impl_trait(async_node_id, span); + if let Some((async_node_id, _)) = sig.header.asyncness.opt_return_id() { + this.record_lifetime_params_for_impl_trait(async_node_id); } }, ); @@ -951,8 +952,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, &declaration.output, ); - if let Some((async_node_id, span)) = async_node_id { - this.record_lifetime_params_for_impl_trait(async_node_id, span); + if let Some((async_node_id, _)) = async_node_id { + this.record_lifetime_params_for_impl_trait(async_node_id); } }, ); @@ -4367,7 +4368,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { /// We include all lifetime parameters, either named or "Fresh". /// The order of those parameters does not matter, as long as it is /// deterministic. - fn record_lifetime_params_for_impl_trait(&mut self, impl_trait_node_id: NodeId, span: Span) { + fn record_lifetime_params_for_impl_trait(&mut self, impl_trait_node_id: NodeId) { let mut extra_lifetime_params = vec![]; for rib in self.lifetime_ribs.iter().rev() { @@ -4380,14 +4381,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { extra_lifetime_params.extend(earlier_fresh); } } - LifetimeRibKind::Generics { .. } => {} - _ => { - // We are in a function definition. We should only find `Generics` - // and `AnonymousCreateParameter` inside the innermost `Item`. - span_bug!(span, "unexpected rib kind: {:?}", rib.kind) - } + _ => {} } } + self.r.extra_lifetime_params_map.insert(impl_trait_node_id, extra_lifetime_params); } |
