From f95bdf453e4f4c0a5ac244ff5878264b61ccaa8e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Oct 2024 21:52:44 -0400 Subject: [PATCH 1/4] Remove redundant in_trait from hir::TyKind::OpaqueDef --- compiler/rustc_ast_lowering/src/lib.rs | 1 - compiler/rustc_borrowck/src/diagnostics/region_name.rs | 2 +- compiler/rustc_hir/src/hir.rs | 4 ++-- compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 2 +- compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs | 2 +- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 4 ++-- compiler/rustc_middle/src/ty/diagnostics.rs | 2 +- compiler/rustc_passes/src/dead.rs | 2 +- .../infer/nice_region_error/static_impl_trait.rs | 2 +- .../rustc_trait_selection/src/error_reporting/infer/region.rs | 2 +- compiler/rustc_ty_utils/src/assoc.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- .../clippy/clippy_lints/src/extra_unused_type_parameters.rs | 2 +- src/tools/clippy/clippy_lints/src/lifetimes.rs | 2 +- src/tools/clippy/clippy_lints/src/manual_async_fn.rs | 2 +- src/tools/clippy/clippy_utils/src/hir_utils.rs | 3 +-- 17 files changed, 18 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c6cb7aa7dd5..8f8fe9e8580 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1776,7 +1776,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TyKind::OpaqueDef( hir::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id } }, generic_args, - in_trait, ) } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 2f22e1532c1..d4598a1f582 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -832,7 +832,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> { let hir = self.infcx.tcx.hir(); - let hir::TyKind::OpaqueDef(id, _, _) = hir_ty.kind else { + let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind else { span_bug!( hir_ty.span, "lowered return type of async fn is not OpaqueDef: {:?}", diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 71216023ecc..ac23443fee2 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2632,7 +2632,7 @@ impl<'hir> Ty<'hir> { } TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty), TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(), - TyKind::OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args), + TyKind::OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args), TyKind::Path(QPath::TypeRelative(ty, segment)) => { ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args) } @@ -2856,7 +2856,7 @@ pub enum TyKind<'hir> { /// possibly parameters) that are actually bound on the `impl Trait`. /// /// The last parameter specifies whether this opaque appears in a trait definition. - OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool), + OpaqueDef(ItemId, &'hir [GenericArg<'hir>]), /// A trait object type `Bound1 + Bound2 + Bound3` /// where `Bound` is a trait or a lifetime. TraitObject( diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 4da32245785..d0a8aaa85bb 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -894,7 +894,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul TyKind::Path(ref qpath) => { try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span)); } - TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => { + TyKind::OpaqueDef(item_id, lifetimes) => { try_visit!(visitor.visit_nested_item(item_id)); walk_list!(visitor, visit_generic_arg, lifetimes); } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 9e970462205..33f6623edfd 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -332,7 +332,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // and the duplicated parameter, to ensure that they do not get out of sync. if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node { let opaque_ty_node = tcx.parent_hir_node(hir_id); - let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node + let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes), .. }) = opaque_ty_node else { bug!("unexpected {opaque_ty_node:?}") }; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index c9b949ad88d..30944b5e990 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -689,7 +689,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { }; self.with(scope, |this| this.visit_ty(mt.ty)); } - hir::TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => { + hir::TyKind::OpaqueDef(item_id, lifetimes) => { // Resolve the lifetimes in the bounds to the lifetime defs in the generics. // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to // `type MyAnonTy<'b> = impl MyTrait<'b>;` diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 2186952720f..496f54e31d2 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2087,11 +2087,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself)); self.lower_path(opt_self_ty, path, hir_ty.hir_id, false) } - &hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => { + &hir::TyKind::OpaqueDef(item_id, lifetimes) => { let opaque_ty = tcx.hir().item(item_id); match opaque_ty.kind { - hir::ItemKind::OpaqueTy(&hir::OpaqueTy { .. }) => { + hir::ItemKind::OpaqueTy(&hir::OpaqueTy { in_trait, .. }) => { let local_def_id = item_id.owner_id.def_id; // If this is an RPITIT and we are using the new RPITIT lowering scheme, we // generate the def_id of an associated type for the trait and return as diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 992eb264163..d98e18c1b0c 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -510,7 +510,7 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> { ) => { self.0.push(ty); } - hir::TyKind::OpaqueDef(item_id, _, _) => { + hir::TyKind::OpaqueDef(item_id, _) => { self.0.push(ty); let item = self.1.item(item_id); hir::intravisit::walk_item(self, item); diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index aa329fc546e..100f3e80603 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -656,7 +656,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { } fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { - if let TyKind::OpaqueDef(item_id, _, _) = ty.kind { + if let TyKind::OpaqueDef(item_id, _) = ty.kind { let item = self.tcx.hir().item(item_id); intravisit::walk_item(self, item); } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index 4bde120cba9..31256bca55e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -284,7 +284,7 @@ pub fn suggest_new_region_bound( } match fn_return.kind { // FIXME(precise_captures): Suggest adding to `use<...>` list instead. - TyKind::OpaqueDef(item_id, _, _) => { + TyKind::OpaqueDef(item_id, _) => { let item = tcx.hir().item(item_id); let ItemKind::OpaqueTy(opaque) = &item.kind else { return; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 41fe8a2bf22..4c3a0112488 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -857,7 +857,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) { - let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind else { + let hir::TyKind::OpaqueDef(item_id, _) = ty.kind else { return hir::intravisit::walk_ty(self, ty); }; let opaque_ty = self.tcx.hir().item(item_id).expect_opaque_ty(); diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 6726db8bb54..45fe199c335 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -323,7 +323,7 @@ fn associated_types_for_impl_traits_in_associated_fn( impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { - if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind + if let hir::TyKind::OpaqueDef(item_id, _) = ty.kind && self.rpits.insert(item_id.owner_id.def_id) { let opaque_item = diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3d845cf878f..b79458eaa78 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1828,7 +1828,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T Array(Box::new(clean_ty(ty, cx)), length.into()) } TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()), - TyKind::OpaqueDef(item_id, _, _) => { + TyKind::OpaqueDef(item_id, _) => { let item = cx.tcx.hir().item(item_id); if let hir::ItemKind::OpaqueTy(ty) = item.kind { ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect()) diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs index bf9388b4a70..a7fb9535e79 100644 --- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs +++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs @@ -199,7 +199,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for TypeWalker<'cx, 'tcx> { fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) { if let Some((def_id, _)) = t.peel_refs().as_generic_param() { self.ty_params.remove(&def_id); - } else if let TyKind::OpaqueDef(id, _, _) = t.kind { + } else if let TyKind::OpaqueDef(id, _) = t.kind { // Explicitly walk OpaqueDef. Normally `walk_ty` would do the job, but it calls // `visit_nested_item`, which checks that `Self::NestedFilter::INTER` is set. We're // using `OnlyBodies`, so the check ends up failing and the type isn't fully walked. diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index 755afe959b3..d3cc5ea628c 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -523,7 +523,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { fn visit_ty(&mut self, ty: &'tcx Ty<'_>) { match ty.kind { - TyKind::OpaqueDef(item, bounds, _) => { + TyKind::OpaqueDef(item, bounds) => { let map = self.cx.tcx.hir(); let item = map.item(item); let len = self.lts.len(); diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index fc3bba9e512..7097c85156c 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -105,7 +105,7 @@ fn future_trait_ref<'tcx>( cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>, ) -> Option<(&'tcx TraitRef<'tcx>, Vec)> { - if let TyKind::OpaqueDef(item_id, bounds, false) = ty.kind + if let TyKind::OpaqueDef(item_id, bounds) = ty.kind && let item = cx.tcx.hir().item(item_id) && let ItemKind::OpaqueTy(opaque) = &item.kind && let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| { diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 76900379ac7..b2d75125ccd 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -1115,9 +1115,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } }, TyKind::Path(ref qpath) => self.hash_qpath(qpath), - TyKind::OpaqueDef(_, arg_list, in_trait) => { + TyKind::OpaqueDef(_, arg_list) => { self.hash_generic_args(arg_list); - in_trait.hash(&mut self.s); }, TyKind::TraitObject(_, lifetime, _) => { self.hash_lifetime(lifetime); From cb7e3695e8e7ea04377f60977b65ba324273b63d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Oct 2024 22:04:18 -0400 Subject: [PATCH 2/4] Use named fields for OpaqueTyOrigin --- compiler/rustc_ast_lowering/src/lib.rs | 12 +++++++----- .../src/region_infer/opaque_types.rs | 4 ++-- compiler/rustc_hir/src/hir.rs | 10 ++++++++-- compiler/rustc_hir_analysis/src/check/check.rs | 16 ++++++++-------- .../src/check/compare_impl_item/refine.rs | 4 ++-- .../src/collect/generics_of.rs | 3 ++- .../src/collect/item_bounds.rs | 4 ++-- .../src/collect/resolve_bound_vars.rs | 4 ++-- .../rustc_hir_analysis/src/collect/type_of.rs | 3 ++- compiler/rustc_hir_typeck/src/_match.rs | 3 ++- .../rustc_lint/src/impl_trait_overcaptures.rs | 4 ++-- .../src/opaque_hidden_inferred_bound.rs | 6 +++--- compiler/rustc_metadata/src/rmeta/encoder.rs | 6 +++--- .../src/error_reporting/infer/region.rs | 2 +- .../error_reporting/traits/fulfillment_errors.rs | 2 +- compiler/rustc_ty_utils/src/assoc.rs | 3 ++- compiler/rustc_ty_utils/src/opaque_types.rs | 3 ++- src/librustdoc/visit_ast.rs | 2 +- src/tools/clippy/clippy_lints/src/len_zero.rs | 2 +- 19 files changed, 53 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8f8fe9e8580..c8aa8d701b9 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1555,7 +1555,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .map(|(ident, id, _)| Lifetime { id, ident }) .collect() } - hir::OpaqueTyOrigin::FnReturn(..) => { + hir::OpaqueTyOrigin::FnReturn { .. } => { if matches!( fn_kind.expect("expected RPITs to be lowered with a FnKind"), FnDeclKind::Impl | FnDeclKind::Trait @@ -1576,7 +1576,7 @@ 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`") } } @@ -1867,7 +1867,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | FnDeclKind::Inherent | FnDeclKind::Trait | FnDeclKind::Impl => ImplTraitContext::OpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)), + origin: hir::OpaqueTyOrigin::FnReturn { + parent: self.local_def_id(fn_node_id), + }, fn_kind: Some(kind), }, FnDeclKind::ExternFn => { @@ -1952,7 +1954,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), + hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id }, matches!(fn_kind, FnDeclKind::Trait), captured_lifetimes, span, @@ -1963,7 +1965,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { coro, opaque_ty_span, ImplTraitContext::OpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), + origin: hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id }, fn_kind: Some(fn_kind), }, ); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 3cf21d4a36b..1f6aa598059 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -503,8 +503,8 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> { let &Self { tcx, def_id, .. } = self; let origin = tcx.opaque_type_origin(def_id); let parent = match origin { - hir::OpaqueTyOrigin::FnReturn(parent) - | hir::OpaqueTyOrigin::AsyncFn(parent) + hir::OpaqueTyOrigin::FnReturn { parent } + | hir::OpaqueTyOrigin::AsyncFn { parent } | hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent, }; let param_env = tcx.param_env(parent); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ac23443fee2..68195c46f5c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2806,9 +2806,15 @@ pub struct PreciseCapturingNonLifetimeArg { #[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)] pub enum OpaqueTyOrigin { /// `-> impl Trait` - FnReturn(LocalDefId), + FnReturn { + /// The defining function. + parent: LocalDefId, + }, /// `async fn` - AsyncFn(LocalDefId), + AsyncFn { + /// The defining function. + parent: LocalDefId, + }, /// type aliases: `type Foo = impl Trait;` TyAlias { /// The type alias or associated type parent of the TAIT/ATPIT diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index d725772a5b3..feba484229b 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -336,9 +336,9 @@ fn check_opaque_meets_bounds<'tcx>( origin: &hir::OpaqueTyOrigin, ) -> Result<(), ErrorGuaranteed> { let defining_use_anchor = match *origin { - hir::OpaqueTyOrigin::FnReturn(did) - | hir::OpaqueTyOrigin::AsyncFn(did) - | hir::OpaqueTyOrigin::TyAlias { parent: did, .. } => did, + hir::OpaqueTyOrigin::FnReturn { parent } + | hir::OpaqueTyOrigin::AsyncFn { parent } + | hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent, }; let param_env = tcx.param_env(defining_use_anchor); @@ -346,8 +346,8 @@ fn check_opaque_meets_bounds<'tcx>( let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let args = match *origin { - hir::OpaqueTyOrigin::FnReturn(parent) - | hir::OpaqueTyOrigin::AsyncFn(parent) + hir::OpaqueTyOrigin::FnReturn { parent } + | hir::OpaqueTyOrigin::AsyncFn { parent } | hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item( tcx, parent, ) @@ -409,7 +409,7 @@ fn check_opaque_meets_bounds<'tcx>( let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?; - if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin { + if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } = origin { // HACK: this should also fall through to the hidden type check below, but the original // implementation had a bug where equivalent lifetimes are not identical. This caused us // to reject existing stable code that is otherwise completely fine. The real fix is to @@ -736,8 +736,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_opaque_precise_captures(tcx, def_id); let origin = tcx.opaque_type_origin(def_id); - if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) - | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin + if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } + | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id } = origin && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index e07b587508a..3375fc303f1 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -94,8 +94,8 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| { matches!( node.expect_item().expect_opaque_ty().origin, - hir::OpaqueTyOrigin::AsyncFn(def_id) | hir::OpaqueTyOrigin::FnReturn(def_id) - if def_id == impl_m.def_id.expect_local() + hir::OpaqueTyOrigin::AsyncFn { parent } | hir::OpaqueTyOrigin::FnReturn { parent } + if parent == impl_m.def_id.expect_local() ) }) { report_mismatched_rpitit_signature( diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 0a8eef2006d..73e98c67cdc 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -210,7 +210,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { Node::Item(item) => match item.kind { ItemKind::OpaqueTy(&hir::OpaqueTy { origin: - hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id), + hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } + | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id }, in_trait, .. }) => { diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index f44b4728ad5..07a8c3a9e84 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -388,8 +388,8 @@ pub(super) fn explicit_item_bounds_with_filter( span, .. }) => { - let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) - | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = *origin + let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } + | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id }) = *origin else { span_bug!(*span, "RPITIT cannot be a TAIT, but got origin {origin:?}"); }; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 30944b5e990..60788641da0 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -515,8 +515,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin: - hir::OpaqueTyOrigin::FnReturn(parent) - | hir::OpaqueTyOrigin::AsyncFn(parent) + hir::OpaqueTyOrigin::FnReturn { parent } + | hir::OpaqueTyOrigin::AsyncFn { parent } | hir::OpaqueTyOrigin::TyAlias { parent, .. }, generics, .. diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 48b5e87cbd0..313d7dd6265 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -618,7 +618,8 @@ pub(super) fn type_of_opaque( // Opaque types desugared from `impl Trait`. ItemKind::OpaqueTy(&OpaqueTy { origin: - hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), + hir::OpaqueTyOrigin::FnReturn { parent: owner } + | hir::OpaqueTyOrigin::AsyncFn { parent: owner }, in_trait, .. }) => { diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index bf8ed017cf7..204138ffd44 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -602,7 +602,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|(k, _)| (k.def_id, k.args))?, _ => return None, }; - let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = self.tcx.opaque_type_origin(def_id) + let hir::OpaqueTyOrigin::FnReturn { parent: parent_def_id } = + self.tcx.opaque_type_origin(def_id) else { return None; }; diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index a073d16f634..c13f4c7746d 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -259,8 +259,8 @@ where // If it's owned by this function && let opaque = self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty() - && let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin - && parent_def_id == self.parent_def_id + && let hir::OpaqueTyOrigin::FnReturn { parent } = opaque.origin + && parent == self.parent_def_id { let opaque_span = self.tcx.def_span(opaque_def_id); let new_capture_rules = diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 83652bbf546..87fa38a282e 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // That's because although we may have an opaque type on the function, // it won't have a hidden type, so proving predicates about it is // not really meaningful. - if let hir::OpaqueTyOrigin::FnReturn(method_def_id) = opaque.origin + if let hir::OpaqueTyOrigin::FnReturn { parent: method_def_id } = opaque.origin && let hir::Node::TraitItem(trait_item) = cx.tcx.hir_node_by_def_id(method_def_id) && !trait_item.defaultness.has_value() { @@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { && cx.tcx.parent(opaque_ty.def_id) == def_id && matches!( opaque.origin, - hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) + hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } ) { return; @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // return type is well-formed in traits even when `Self` isn't sized. if let ty::Param(param_ty) = *proj_term.kind() && param_ty.name == kw::SelfUpper - && matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(_)) + && matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn { .. }) && opaque.in_trait { return; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 5f756672b04..61eb7260384 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1186,9 +1186,9 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> DefKind::OpaqueTy => { let origin = tcx.opaque_type_origin(def_id); - if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) - | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin - && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) + if let hir::OpaqueTyOrigin::FnReturn { parent } + | hir::OpaqueTyOrigin::AsyncFn { parent } = origin + && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(parent) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { false diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 4c3a0112488..673756076b1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -1271,7 +1271,7 @@ fn suggest_precise_capturing<'tcx>( let hir::OpaqueTy { bounds, origin, .. } = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); - let hir::OpaqueTyOrigin::FnReturn(fn_def_id) = *origin else { + let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } = *origin else { return; }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 34a0f182ab4..43762b1004b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2580,7 +2580,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { def_id: DefId, ) -> ErrorGuaranteed { let name = match self.tcx.opaque_type_origin(def_id.expect_local()) { - hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => { + hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } => { "opaque type".to_string() } hir::OpaqueTyOrigin::TyAlias { .. } => { diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 45fe199c335..f8cfeb500a5 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -379,7 +379,8 @@ fn associated_type_for_impl_trait_in_trait( tcx: TyCtxt<'_>, opaque_ty_def_id: LocalDefId, ) -> LocalDefId { - let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = + let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } + | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id }) = tcx.opaque_type_origin(opaque_ty_def_id) else { bug!("expected opaque for {opaque_ty_def_id:?}"); diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index bac0d020d72..7c4b4887b2d 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -141,7 +141,8 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local()); trace!(?origin); match origin { - rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {} + rustc_hir::OpaqueTyOrigin::FnReturn { .. } + | rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {} rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => { if !in_assoc_ty && !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) { return; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 2cf703f57c0..c44e5ecaba8 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -515,7 +515,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.add_to_current_mod(item, renamed, import_id); } hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::AsyncFn(_) | hir::OpaqueTyOrigin::FnReturn(_), + origin: hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::FnReturn { .. }, .. }) => { // return-position impl traits are never nameable, and should never be documented. diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 8bc2a56af99..0cbcdbeb90a 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -313,7 +313,7 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<& kind: ItemKind::OpaqueTy(opaque), .. } = item - && let OpaqueTyOrigin::AsyncFn(_) = opaque.origin + && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds && let Some(segment) = trait_ref.trait_ref.path.segments.last() && let Some(generic_args) = segment.args From 7cd466a03606313dad4fa22fd5cf444204138fc8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Oct 2024 22:21:37 -0400 Subject: [PATCH 3/4] Move in_trait into OpaqueTyOrigin --- compiler/rustc_ast_lowering/src/item.rs | 2 - compiler/rustc_ast_lowering/src/lib.rs | 80 +++++++++---------- .../src/region_infer/opaque_types.rs | 4 +- compiler/rustc_hir/src/hir.rs | 14 +++- .../rustc_hir_analysis/src/check/check.rs | 12 +-- .../src/check/compare_impl_item/refine.rs | 2 +- .../src/collect/generics_of.rs | 7 +- .../src/collect/item_bounds.rs | 70 +++++++++------- .../src/collect/resolve_bound_vars.rs | 4 +- .../rustc_hir_analysis/src/collect/type_of.rs | 9 ++- .../src/hir_ty_lowering/mod.rs | 34 ++++++-- compiler/rustc_hir_typeck/src/_match.rs | 2 +- .../rustc_lint/src/impl_trait_overcaptures.rs | 2 +- .../src/opaque_hidden_inferred_bound.rs | 8 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 4 +- compiler/rustc_middle/src/hir/map/mod.rs | 8 +- compiler/rustc_privacy/src/lib.rs | 3 +- .../src/error_reporting/infer/region.rs | 2 +- compiler/rustc_ty_utils/src/assoc.rs | 4 +- 19 files changed, 146 insertions(+), 125 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 7bb3b2fa290..1273b50dff8 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -286,7 +286,6 @@ impl<'hir> LoweringContext<'_, 'hir> { parent: this.local_def_id(id), in_assoc_ty: false, }, - fn_kind: None, }), }, ); @@ -983,7 +982,6 @@ impl<'hir> LoweringContext<'_, 'hir> { parent: this.local_def_id(i.id), in_assoc_ty: true, }, - fn_kind: None, }); hir::ImplItemKind::Type(ty) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c8aa8d701b9..9275308cccb 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, - }, + 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, 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 @@ -1583,9 +1570,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; 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,7 +1597,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, opaque_ty_node_id: NodeId, origin: hir::OpaqueTyOrigin, - in_trait: bool, captured_lifetimes_to_duplicate: FxIndexSet, span: Span, opaque_ty_span: Span, @@ -1747,7 +1725,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds, origin, lifetime_mapping, - in_trait, }; // Generate an `type Foo = impl Trait;` declaration. @@ -1863,14 +1840,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 { + 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), }, - fn_kind: Some(kind), }, FnDeclKind::ExternFn => { ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn) @@ -1952,10 +1938,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 { parent: 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, @@ -1965,8 +1957,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { coro, opaque_ty_span, ImplTraitContext::OpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id }, - fn_kind: Some(fn_kind), + origin: hir::OpaqueTyOrigin::FnReturn { + parent: fn_def_id, + in_trait_or_impl, + }, }, ); arena_vec![this; bound] diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 1f6aa598059..2f90e916281 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -503,8 +503,8 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> { let &Self { tcx, def_id, .. } = self; let origin = tcx.opaque_type_origin(def_id); let parent = match origin { - hir::OpaqueTyOrigin::FnReturn { parent } - | hir::OpaqueTyOrigin::AsyncFn { parent } + hir::OpaqueTyOrigin::FnReturn { parent, .. } + | hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent, }; let param_env = tcx.param_env(parent); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 68195c46f5c..f58ec22aea9 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2762,10 +2762,6 @@ pub struct OpaqueTy<'hir> { /// This mapping associated a captured lifetime (first parameter) with the new /// early-bound lifetime that was generated for the opaque. pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)], - /// Whether the opaque is a return-position impl trait (or async future) - /// originating from a trait method. This makes it so that the opaque is - /// lowered as an associated type. - pub in_trait: bool, } #[derive(Debug, Clone, Copy, HashStable_Generic)] @@ -2802,6 +2798,12 @@ pub struct PreciseCapturingNonLifetimeArg { pub res: Res, } +#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)] +pub enum RpitContext { + Trait, + TraitImpl, +} + /// From whence the opaque type came. #[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)] pub enum OpaqueTyOrigin { @@ -2809,11 +2811,15 @@ pub enum OpaqueTyOrigin { FnReturn { /// The defining function. parent: LocalDefId, + // Whether this is an RPITIT (return position impl trait in trait) + in_trait_or_impl: Option, }, /// `async fn` AsyncFn { /// The defining function. parent: LocalDefId, + // Whether this is an AFIT (async fn in trait) + in_trait_or_impl: Option, }, /// type aliases: `type Foo = impl Trait;` TyAlias { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index feba484229b..312212232bc 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -336,8 +336,8 @@ fn check_opaque_meets_bounds<'tcx>( origin: &hir::OpaqueTyOrigin, ) -> Result<(), ErrorGuaranteed> { let defining_use_anchor = match *origin { - hir::OpaqueTyOrigin::FnReturn { parent } - | hir::OpaqueTyOrigin::AsyncFn { parent } + hir::OpaqueTyOrigin::FnReturn { parent, .. } + | hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent, }; let param_env = tcx.param_env(defining_use_anchor); @@ -346,8 +346,8 @@ fn check_opaque_meets_bounds<'tcx>( let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let args = match *origin { - hir::OpaqueTyOrigin::FnReturn { parent } - | hir::OpaqueTyOrigin::AsyncFn { parent } + hir::OpaqueTyOrigin::FnReturn { parent, .. } + | hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item( tcx, parent, ) @@ -736,8 +736,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_opaque_precise_captures(tcx, def_id); let origin = tcx.opaque_type_origin(def_id); - if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } - | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id } = origin + if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } + | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } = origin && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 3375fc303f1..35c2b7e7ce2 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -94,7 +94,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| { matches!( node.expect_item().expect_opaque_ty().origin, - hir::OpaqueTyOrigin::AsyncFn { parent } | hir::OpaqueTyOrigin::FnReturn { parent } + hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. } if parent == impl_m.def_id.expect_local() ) }) { diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 73e98c67cdc..8ff9640a874 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -210,12 +210,11 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { Node::Item(item) => match item.kind { ItemKind::OpaqueTy(&hir::OpaqueTy { origin: - hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } - | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id }, - in_trait, + hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl } + | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl }, .. }) => { - if in_trait { + if in_trait_or_impl.is_some() { assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn); } else { assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn); diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 07a8c3a9e84..2418037ae96 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -370,39 +370,47 @@ pub(super) fn explicit_item_bounds_with_filter( .. }) => associated_type_bounds(tcx, def_id, bounds, *span, filter), hir::Node::Item(hir::Item { - kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: false, .. }), + kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, origin, .. }), span, .. - }) => { - let args = GenericArgs::identity_for_item(tcx, def_id); - let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); - let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter); - assert_only_contains_predicates_from(filter, bounds, item_ty); - bounds - } - // Since RPITITs are lowered as projections in `::lower_ty`, when we're - // asking for the item bounds of the *opaques* in a trait's default method signature, we - // need to map these projections back to opaques. - hir::Node::Item(hir::Item { - kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: true, origin, .. }), - span, - .. - }) => { - let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } - | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id }) = *origin - else { - span_bug!(*span, "RPITIT cannot be a TAIT, but got origin {origin:?}"); - }; - let args = GenericArgs::identity_for_item(tcx, def_id); - let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); - let bounds = &*tcx.arena.alloc_slice( - &opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter) - .to_vec() - .fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }), - ); - assert_only_contains_predicates_from(filter, bounds, item_ty); - bounds - } + }) => match origin { + // Since RPITITs are lowered as projections in `::lower_ty`, + // when we're asking for the item bounds of the *opaques* in a trait's default + // method signature, we need to map these projections back to opaques. + rustc_hir::OpaqueTyOrigin::FnReturn { + parent, + in_trait_or_impl: Some(hir::RpitContext::Trait), + } + | rustc_hir::OpaqueTyOrigin::AsyncFn { + parent, + in_trait_or_impl: Some(hir::RpitContext::Trait), + } => { + let args = GenericArgs::identity_for_item(tcx, def_id); + let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); + let bounds = &*tcx.arena.alloc_slice( + &opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter) + .to_vec() + .fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: parent.to_def_id() }), + ); + assert_only_contains_predicates_from(filter, bounds, item_ty); + bounds + } + rustc_hir::OpaqueTyOrigin::FnReturn { + parent: _, + in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), + } + | rustc_hir::OpaqueTyOrigin::AsyncFn { + parent: _, + in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), + } + | rustc_hir::OpaqueTyOrigin::TyAlias { parent: _, .. } => { + let args = GenericArgs::identity_for_item(tcx, def_id); + let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); + let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter); + assert_only_contains_predicates_from(filter, bounds, item_ty); + bounds + } + }, hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[], _ => bug!("item_bounds called on {:?}", def_id), }; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 60788641da0..a15621bf28b 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -515,8 +515,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin: - hir::OpaqueTyOrigin::FnReturn { parent } - | hir::OpaqueTyOrigin::AsyncFn { parent } + hir::OpaqueTyOrigin::FnReturn { parent, .. } + | hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::TyAlias { parent, .. }, generics, .. diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 313d7dd6265..3af4d1f5eda 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -618,12 +618,13 @@ pub(super) fn type_of_opaque( // Opaque types desugared from `impl Trait`. ItemKind::OpaqueTy(&OpaqueTy { origin: - hir::OpaqueTyOrigin::FnReturn { parent: owner } - | hir::OpaqueTyOrigin::AsyncFn { parent: owner }, - in_trait, + hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl } + | hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl }, .. }) => { - if in_trait && !tcx.defaultness(owner).has_value() { + if in_trait_or_impl == Some(hir::RpitContext::Trait) + && !tcx.defaultness(owner).has_value() + { span_bug!( tcx.def_span(def_id), "tried to get type of this RPITIT with no definition" diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 496f54e31d2..24a8fdf0f6b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2091,17 +2091,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let opaque_ty = tcx.hir().item(item_id); match opaque_ty.kind { - hir::ItemKind::OpaqueTy(&hir::OpaqueTy { in_trait, .. }) => { + hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => { let local_def_id = item_id.owner_id.def_id; // If this is an RPITIT and we are using the new RPITIT lowering scheme, we // generate the def_id of an associated type for the trait and return as // type a projection. - let def_id = if in_trait { - tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id() - } else { - local_def_id.to_def_id() - }; - self.lower_opaque_ty(def_id, lifetimes, in_trait) + match origin { + hir::OpaqueTyOrigin::FnReturn { + in_trait_or_impl: Some(hir::RpitContext::Trait), + .. + } + | hir::OpaqueTyOrigin::AsyncFn { + in_trait_or_impl: Some(hir::RpitContext::Trait), + .. + } => self.lower_opaque_ty( + tcx.associated_type_for_impl_trait_in_trait(local_def_id) + .to_def_id(), + lifetimes, + true, + ), + hir::OpaqueTyOrigin::FnReturn { + in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), + .. + } + | hir::OpaqueTyOrigin::AsyncFn { + in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), + .. + } + | hir::OpaqueTyOrigin::TyAlias { .. } => { + self.lower_opaque_ty(local_def_id.to_def_id(), lifetimes, false) + } + } } ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), } diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 204138ffd44..2dbadf8198b 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -602,7 +602,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|(k, _)| (k.def_id, k.args))?, _ => return None, }; - let hir::OpaqueTyOrigin::FnReturn { parent: parent_def_id } = + let hir::OpaqueTyOrigin::FnReturn { parent: parent_def_id, .. } = self.tcx.opaque_type_origin(def_id) else { return None; diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index c13f4c7746d..5aeaad42069 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -259,7 +259,7 @@ where // If it's owned by this function && let opaque = self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty() - && let hir::OpaqueTyOrigin::FnReturn { parent } = opaque.origin + && let hir::OpaqueTyOrigin::FnReturn { parent, .. } = opaque.origin && parent == self.parent_def_id { let opaque_span = self.tcx.def_span(opaque_def_id); diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 87fa38a282e..342ebfa0b06 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // That's because although we may have an opaque type on the function, // it won't have a hidden type, so proving predicates about it is // not really meaningful. - if let hir::OpaqueTyOrigin::FnReturn { parent: method_def_id } = opaque.origin + if let hir::OpaqueTyOrigin::FnReturn { parent: method_def_id, .. } = opaque.origin && let hir::Node::TraitItem(trait_item) = cx.tcx.hir_node_by_def_id(method_def_id) && !trait_item.defaultness.has_value() { @@ -114,8 +114,10 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // return type is well-formed in traits even when `Self` isn't sized. if let ty::Param(param_ty) = *proj_term.kind() && param_ty.name == kw::SelfUpper - && matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn { .. }) - && opaque.in_trait + && matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn { + in_trait_or_impl: Some(hir::RpitContext::Trait), + .. + }) { return; } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 61eb7260384..610c682d3a4 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1186,8 +1186,8 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> DefKind::OpaqueTy => { let origin = tcx.opaque_type_origin(def_id); - if let hir::OpaqueTyOrigin::FnReturn { parent } - | hir::OpaqueTyOrigin::AsyncFn { parent } = origin + if let hir::OpaqueTyOrigin::FnReturn { parent, .. } + | hir::OpaqueTyOrigin::AsyncFn { parent, .. } = origin && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(parent) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index e11361a615f..72e6c96e6f6 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1139,13 +1139,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { ItemKind::ForeignMod { .. } => "foreign mod", ItemKind::GlobalAsm(..) => "global asm", ItemKind::TyAlias(..) => "ty", - ItemKind::OpaqueTy(opaque) => { - if opaque.in_trait { - "opaque type in trait" - } else { - "opaque type" - } - } + ItemKind::OpaqueTy(..) => "opaque type", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", ItemKind::Union(..) => "union", diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 9094b00fbfb..015e45ad670 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -636,8 +636,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { if self.impl_trait_pass - && let hir::ItemKind::OpaqueTy(opaque) = item.kind - && !opaque.in_trait + && let hir::ItemKind::OpaqueTy(..) = item.kind { // FIXME: This is some serious pessimization intended to workaround deficiencies // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 673756076b1..a2d717817db 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -1271,7 +1271,7 @@ fn suggest_precise_capturing<'tcx>( let hir::OpaqueTy { bounds, origin, .. } = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); - let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } = *origin else { + let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } = *origin else { return; }; diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index f8cfeb500a5..e41f2c8ce48 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -379,8 +379,8 @@ fn associated_type_for_impl_trait_in_trait( tcx: TyCtxt<'_>, opaque_ty_def_id: LocalDefId, ) -> LocalDefId { - let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id } - | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id }) = + let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } + | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. }) = tcx.opaque_type_origin(opaque_ty_def_id) else { bug!("expected opaque for {opaque_ty_def_id:?}"); From 6e8573c520086db6cc7993a1a2608cc9347832a4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Oct 2024 23:00:08 -0400 Subject: [PATCH 4/4] Visit in embargo visitor if trait method has body --- compiler/rustc_privacy/src/lib.rs | 48 ++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 015e45ad670..d00e7eff752 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -636,17 +636,45 @@ impl<'tcx> EmbargoVisitor<'tcx> { impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { if self.impl_trait_pass - && let hir::ItemKind::OpaqueTy(..) = item.kind + && let hir::ItemKind::OpaqueTy(opaque) = item.kind { - // FIXME: This is some serious pessimization intended to workaround deficiencies - // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time - // reachable if they are returned via `impl Trait`, even from private functions. - let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public); - self.reach_through_impl_trait(item.owner_id.def_id, pub_ev) - .generics() - .predicates() - .ty(); - return; + let should_visit = match opaque.origin { + hir::OpaqueTyOrigin::FnReturn { + parent, + in_trait_or_impl: Some(hir::RpitContext::Trait), + } + | hir::OpaqueTyOrigin::AsyncFn { + parent, + in_trait_or_impl: Some(hir::RpitContext::Trait), + } => match self.tcx.hir_node_by_def_id(parent).expect_trait_item().expect_fn().1 { + hir::TraitFn::Required(_) => false, + hir::TraitFn::Provided(..) => true, + }, + + // Always visit RPITs in functions that have definitions, + // and all TAITs. + hir::OpaqueTyOrigin::FnReturn { + in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), + .. + } + | hir::OpaqueTyOrigin::AsyncFn { + in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), + .. + } + | hir::OpaqueTyOrigin::TyAlias { .. } => true, + }; + + if should_visit { + // FIXME: This is some serious pessimization intended to workaround deficiencies + // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time + // reachable if they are returned via `impl Trait`, even from private functions. + let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public); + self.reach_through_impl_trait(item.owner_id.def_id, pub_ev) + .generics() + .predicates() + .ty(); + return; + } } // Update levels of nested things and mark all items