diff options
Diffstat (limited to 'compiler/rustc_ast_lowering/src/lib.rs')
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 114 |
1 files changed, 50 insertions, 64 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c6cb7aa7dd5..b26797f4203 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -288,12 +288,7 @@ enum ImplTraitContext { /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`. /// - OpaqueTy { - origin: hir::OpaqueTyOrigin, - /// Only used to change the lifetime capture rules, since - /// RPITIT captures all in scope, RPIT does not. - fn_kind: Option<FnDeclKind>, - }, + OpaqueTy { origin: hir::OpaqueTyOrigin }, /// `impl Trait` is unstably accepted in this position. FeatureGated(ImplTraitPosition, Symbol), /// `impl Trait` is not accepted in this position. @@ -1404,14 +1399,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { TyKind::ImplTrait(def_node_id, bounds) => { let span = t.span; match itctx { - ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait( - span, - origin, - *def_node_id, - bounds, - fn_kind, - itctx, - ), + ImplTraitContext::OpaqueTy { origin } => { + self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx) + } ImplTraitContext::Universal => { if let Some(span) = bounds.iter().find_map(|bound| match *bound { ast::GenericBound::Use(_, span) => Some(span), @@ -1513,7 +1503,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { origin: hir::OpaqueTyOrigin, opaque_ty_node_id: NodeId, bounds: &GenericBounds, - fn_kind: Option<FnDeclKind>, itctx: ImplTraitContext, ) -> hir::TyKind<'hir> { // Make sure we know that some funky desugaring has been going on here. @@ -1555,11 +1544,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .map(|(ident, id, _)| Lifetime { id, ident }) .collect() } - hir::OpaqueTyOrigin::FnReturn(..) => { - if matches!( - fn_kind.expect("expected RPITs to be lowered with a FnKind"), - FnDeclKind::Impl | FnDeclKind::Trait - ) || self.tcx.features().lifetime_capture_rules_2024 + hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => { + if in_trait_or_impl.is_some() + || self.tcx.features().lifetime_capture_rules_2024 || span.at_least_rust_2024() { // return-position impl trait in trait was decided to capture all @@ -1576,16 +1563,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { lifetime_collector::lifetimes_in_bounds(self.resolver, bounds) } } - hir::OpaqueTyOrigin::AsyncFn(..) => { + hir::OpaqueTyOrigin::AsyncFn { .. } => { unreachable!("should be using `lower_async_fn_ret_ty`") } } }; debug!(?captured_lifetimes_to_duplicate); - match fn_kind { - // Deny `use<>` on RPITIT in trait/trait-impl for now. - Some(FnDeclKind::Trait | FnDeclKind::Impl) => { + // Feature gate for RPITIT + use<..> + match origin { + rustc_hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl: Some(_), .. } => { if let Some(span) = bounds.iter().find_map(|bound| match *bound { ast::GenericBound::Use(_, span) => Some(span), _ => None, @@ -1593,20 +1580,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnRpitit { span }); } } - None - | Some( - FnDeclKind::Fn - | FnDeclKind::Inherent - | FnDeclKind::ExternFn - | FnDeclKind::Closure - | FnDeclKind::Pointer, - ) => {} + _ => {} } self.lower_opaque_inner( opaque_ty_node_id, origin, - matches!(fn_kind, Some(FnDeclKind::Trait)), captured_lifetimes_to_duplicate, span, opaque_ty_span, @@ -1618,14 +1597,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, opaque_ty_node_id: NodeId, origin: hir::OpaqueTyOrigin, - in_trait: bool, captured_lifetimes_to_duplicate: FxIndexSet<Lifetime>, span: Span, opaque_ty_span: Span, lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>], ) -> hir::TyKind<'hir> { let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id); - debug!(?opaque_ty_def_id); + let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id); + debug!(?opaque_ty_def_id, ?opaque_ty_hir_id); // Map from captured (old) lifetime to synthetic (new) lifetime. // Used to resolve lifetimes in the bounds of the opaque. @@ -1698,7 +1677,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - self.with_hir_id_owner(opaque_ty_node_id, |this| { + let opaque_ty_def = self.with_def_id_parent(opaque_ty_def_id, |this| { // Install the remapping from old to new (if any). This makes sure that // any lifetimes that would have resolved to the def-id of captured // lifetimes are remapped to the new *synthetic* lifetimes of the opaque. @@ -1736,7 +1715,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lifetime_mapping = self.arena.alloc_slice(&synthesized_lifetime_args); - let opaque_ty_item = hir::OpaqueTy { + trace!("registering opaque type with id {:#?}", opaque_ty_def_id); + let opaque_ty_def = hir::OpaqueTy { + hir_id: opaque_ty_hir_id, + def_id: opaque_ty_def_id, generics: this.arena.alloc(hir::Generics { params: generic_params, predicates: &[], @@ -1747,20 +1729,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds, origin, lifetime_mapping, - in_trait, - }; - - // Generate an `type Foo = impl Trait;` declaration. - trace!("registering opaque type with id {:#?}", opaque_ty_def_id); - let opaque_ty_item = hir::Item { - owner_id: hir::OwnerId { def_id: opaque_ty_def_id }, - ident: Ident::empty(), - kind: hir::ItemKind::OpaqueTy(this.arena.alloc(opaque_ty_item)), - vis_span: this.lower_span(span.shrink_to_lo()), span: this.lower_span(opaque_ty_span), }; - - hir::OwnerNode::Item(this.arena.alloc(opaque_ty_item)) + this.arena.alloc(opaque_ty_def) }); let generic_args = self.arena.alloc_from_iter( @@ -1773,11 +1744,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Foo = impl Trait` is, internally, created as a child of the // async fn, so the *type parameters* are inherited. It's // only the lifetime parameters that we must supply. - hir::TyKind::OpaqueDef( - hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } }, - generic_args, - in_trait, - ) + hir::TyKind::OpaqueDef(opaque_ty_def, generic_args) } fn lower_precise_capturing_args( @@ -1864,12 +1831,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { None => match &decl.output { FnRetTy::Ty(ty) => { let itctx = match kind { - FnDeclKind::Fn - | FnDeclKind::Inherent - | FnDeclKind::Trait - | FnDeclKind::Impl => ImplTraitContext::OpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)), - fn_kind: Some(kind), + FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy { + origin: hir::OpaqueTyOrigin::FnReturn { + parent: self.local_def_id(fn_node_id), + in_trait_or_impl: None, + }, + }, + FnDeclKind::Trait => ImplTraitContext::OpaqueTy { + origin: hir::OpaqueTyOrigin::FnReturn { + parent: self.local_def_id(fn_node_id), + in_trait_or_impl: Some(hir::RpitContext::Trait), + }, + }, + FnDeclKind::Impl => ImplTraitContext::OpaqueTy { + origin: hir::OpaqueTyOrigin::FnReturn { + parent: self.local_def_id(fn_node_id), + in_trait_or_impl: Some(hir::RpitContext::TraitImpl), + }, }, FnDeclKind::ExternFn => { ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn) @@ -1951,10 +1929,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .map(|(ident, id, _)| Lifetime { id, ident }) .collect(); + let in_trait_or_impl = match fn_kind { + FnDeclKind::Trait => Some(hir::RpitContext::Trait), + FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl), + FnDeclKind::Fn | FnDeclKind::Inherent => None, + FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(), + }; + let opaque_ty_ref = self.lower_opaque_inner( opaque_ty_node_id, - hir::OpaqueTyOrigin::AsyncFn(fn_def_id), - matches!(fn_kind, FnDeclKind::Trait), + hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl }, captured_lifetimes, span, opaque_ty_span, @@ -1964,8 +1948,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { coro, opaque_ty_span, ImplTraitContext::OpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), - fn_kind: Some(fn_kind), + origin: hir::OpaqueTyOrigin::FnReturn { + parent: fn_def_id, + in_trait_or_impl, + }, }, ); arena_vec![this; bound] |
