From e093b82a41906c8c228643314e2f799568b37ee9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Oct 2024 23:16:31 -0400 Subject: [PATCH] Encode cross-crate opaque type origin --- compiler/rustc_ast_lowering/src/lib.rs | 6 +++--- .../src/region_infer/opaque_types.rs | 2 +- compiler/rustc_hir/src/hir.rs | 16 +++++++++------- compiler/rustc_hir_analysis/src/check/check.rs | 4 ++-- compiler/rustc_hir_analysis/src/collect.rs | 17 +++++++++++++---- .../src/hir_ty_lowering/mod.rs | 3 ++- compiler/rustc_hir_typeck/src/_match.rs | 2 +- .../rustc_infer/src/infer/opaque_types/mod.rs | 5 ++++- .../src/rmeta/decoder/cstore_impl.rs | 5 +---- compiler/rustc_metadata/src/rmeta/encoder.rs | 6 ++---- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_middle/src/query/erase.rs | 1 + compiler/rustc_middle/src/query/mod.rs | 5 ++--- compiler/rustc_middle/src/ty/context.rs | 8 +++----- compiler/rustc_middle/src/ty/parameterized.rs | 1 + .../error_reporting/infer/note_and_explain.rs | 5 ++++- .../traits/fulfillment_errors.rs | 2 +- compiler/rustc_ty_utils/src/assoc.rs | 4 +--- compiler/rustc_ty_utils/src/opaque_types.rs | 2 +- 19 files changed, 53 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e1ee3d0af49..5a0e9e8aec0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -272,7 +272,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 }, + OpaqueTy { origin: hir::OpaqueTyOrigin }, /// `impl Trait` is unstably accepted in this position. FeatureGated(ImplTraitPosition, Symbol), /// `impl Trait` is not accepted in this position. @@ -1416,7 +1416,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_opaque_impl_trait( &mut self, span: Span, - origin: hir::OpaqueTyOrigin, + origin: hir::OpaqueTyOrigin, opaque_ty_node_id: NodeId, bounds: &GenericBounds, itctx: ImplTraitContext, @@ -1458,7 +1458,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_opaque_inner( &mut self, opaque_ty_node_id: NodeId, - origin: hir::OpaqueTyOrigin, + origin: hir::OpaqueTyOrigin, opaque_ty_span: Span, lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>], ) -> hir::TyKind<'hir> { diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 741dac9e763..3a2f5c35c72 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -502,7 +502,7 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> { } let &Self { tcx, def_id, .. } = self; - let origin = tcx.opaque_type_origin(def_id); + let origin = tcx.local_opaque_ty_origin(def_id); let parent = match origin { hir::OpaqueTyOrigin::FnReturn { parent, .. } | hir::OpaqueTyOrigin::AsyncFn { parent, .. } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 12b01266a93..fa76f8652ea 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2746,7 +2746,7 @@ pub struct OpaqueTy<'hir> { pub hir_id: HirId, pub def_id: LocalDefId, pub bounds: GenericBounds<'hir>, - pub origin: OpaqueTyOrigin, + pub origin: OpaqueTyOrigin, pub span: Span, } @@ -2784,33 +2784,35 @@ pub struct PreciseCapturingNonLifetimeArg { pub res: Res, } -#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(HashStable_Generic, Encodable, Decodable)] pub enum RpitContext { Trait, TraitImpl, } /// From whence the opaque type came. -#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)] -pub enum OpaqueTyOrigin { +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(HashStable_Generic, Encodable, Decodable)] +pub enum OpaqueTyOrigin { /// `-> impl Trait` FnReturn { /// The defining function. - parent: LocalDefId, + parent: D, // Whether this is an RPITIT (return position impl trait in trait) in_trait_or_impl: Option, }, /// `async fn` AsyncFn { /// The defining function. - parent: LocalDefId, + parent: D, // Whether this is an AFIT (async fn in trait) in_trait_or_impl: Option, }, /// type aliases: `type Foo = impl Trait;` TyAlias { /// The type alias or associated type parent of the TAIT/ATPIT - parent: LocalDefId, + parent: D, /// associated types in impl blocks for traits. in_assoc_ty: bool, }, diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f830108a02f..29555ebff50 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -268,7 +268,7 @@ fn check_opaque_meets_bounds<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span, - origin: &hir::OpaqueTyOrigin, + origin: &hir::OpaqueTyOrigin, ) -> Result<(), ErrorGuaranteed> { let defining_use_anchor = match *origin { hir::OpaqueTyOrigin::FnReturn { parent, .. } @@ -677,7 +677,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { DefKind::OpaqueTy => { check_opaque_precise_captures(tcx, def_id); - let origin = tcx.opaque_type_origin(def_id); + let origin = tcx.local_opaque_ty_origin(def_id); 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) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c41117d213f..3f6198dbd31 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -86,7 +86,7 @@ pub fn provide(providers: &mut Providers) { impl_trait_header, coroutine_kind, coroutine_for_closure, - is_type_alias_impl_trait, + opaque_ty_origin, rendered_precise_capturing_args, ..*providers }; @@ -1759,9 +1759,18 @@ fn coroutine_for_closure(tcx: TyCtxt<'_>, def_id: LocalDefId) -> DefId { def_id.to_def_id() } -fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { - let opaque = tcx.hir().expect_opaque_ty(def_id); - matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. }) +fn opaque_ty_origin<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> hir::OpaqueTyOrigin { + match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { + hir::OpaqueTyOrigin::FnReturn { parent, in_trait_or_impl } => { + hir::OpaqueTyOrigin::FnReturn { parent: parent.to_def_id(), in_trait_or_impl } + } + hir::OpaqueTyOrigin::AsyncFn { parent, in_trait_or_impl } => { + hir::OpaqueTyOrigin::AsyncFn { parent: parent.to_def_id(), in_trait_or_impl } + } + hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty } => { + hir::OpaqueTyOrigin::TyAlias { parent: parent.to_def_id(), in_assoc_ty } + } + } } fn rendered_precise_capturing_args<'tcx>( 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 2bd8a5223aa..d70e4d8345a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -20,6 +20,7 @@ pub mod errors; pub mod generics; mod lint; +use std::assert_matches::assert_matches; use std::slice; use rustc_ast::TraitObjectSyntax; @@ -1811,7 +1812,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { match path.res { Res::Def(DefKind::OpaqueTy, did) => { // Check for desugared `impl Trait`. - assert!(tcx.is_type_alias_impl_trait(did)); + assert_matches!(tcx.opaque_ty_origin(did), hir::OpaqueTyOrigin::TyAlias { .. }); let item_segment = path.segments.split_last().unwrap(); let _ = self .prohibit_generic_args(item_segment.1.iter(), GenericsArgsErrExtend::OpaqueTy); diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 3372cae7a51..1774772b50b 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -601,7 +601,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => return None, }; let hir::OpaqueTyOrigin::FnReturn { parent: parent_def_id, .. } = - self.tcx.opaque_type_origin(def_id) + self.tcx.local_opaque_ty_origin(def_id) else { return None; }; diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 498d25aea64..2bc006c37da 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -155,7 +155,10 @@ impl<'tcx> InferCtxt<'tcx> { // however in `fn fut() -> impl Future { async { 42 } }`, where // it is of no concern, so we only check for TAITs. if self.can_define_opaque_ty(b_def_id) - && self.tcx.is_type_alias_impl_trait(b_def_id) + && matches!( + self.tcx.opaque_ty_origin(b_def_id), + hir::OpaqueTyOrigin::TyAlias { .. } + ) { self.dcx().emit_err(OpaqueHiddenTypeDiag { span, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 926eb4f6210..f06f2fdc5e5 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -316,10 +316,7 @@ provide! { tcx, def_id, other, cdata, }) .unwrap_or_default() } - is_type_alias_impl_trait => { - debug_assert_eq!(tcx.def_kind(def_id), DefKind::OpaqueTy); - cdata.root.tables.is_type_alias_impl_trait.get(cdata, def_id.index) - } + opaque_ty_origin => { table } assumed_wf_types_for_rpitit => { table } collect_return_position_impl_trait_in_trait_tys => { Ok(cdata diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b5ac302c597..4dafe36f5cd 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1188,7 +1188,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::SyntheticCoroutineBody => true, DefKind::OpaqueTy => { - let origin = tcx.opaque_type_origin(def_id); + let origin = tcx.local_opaque_ty_origin(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) @@ -1530,9 +1530,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::OpaqueTy = def_kind { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_super_predicates(def_id); - self.tables - .is_type_alias_impl_trait - .set(def_id.index, self.tcx.is_type_alias_impl_trait(def_id)); + record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id)); self.encode_precise_capturing_args(def_id); } if tcx.impl_method_has_trait_impl_trait_tys(def_id) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index f1844045677..082dac5f8e7 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -378,7 +378,6 @@ define_tables! { - defaulted: intrinsic: Table>>, is_macro_rules: Table, - is_type_alias_impl_trait: Table, type_alias_is_lazy: Table, attr_flags: Table, // The u64 is the crate-local part of the DefPathHash. All hashes in this crate have the same @@ -469,6 +468,7 @@ define_tables! { doc_link_resolutions: Table>, doc_link_traits_in_scope: Table>, assumed_wf_types_for_rpitit: Table, Span)>>, + opaque_ty_origin: Table>>, } #[derive(TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 5f8427bd707..8cfc7f1e33e 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -280,6 +280,7 @@ trivial! { rustc_hir::IsAsync, rustc_hir::ItemLocalId, rustc_hir::LangItem, + rustc_hir::OpaqueTyOrigin, rustc_hir::OwnerId, rustc_hir::Upvar, rustc_index::bit_set::FiniteBitSet, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d7f58963101..088b5d4ec96 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -260,11 +260,10 @@ rustc_queries! { separate_provide_extern } - query is_type_alias_impl_trait(key: DefId) -> bool + query opaque_ty_origin(key: DefId) -> hir::OpaqueTyOrigin { - desc { "determine whether the opaque is a type-alias impl trait" } + desc { "determine where the opaque originates from" } separate_provide_extern - feedable } query unsizing_params_for_adt(key: DefId) -> &'tcx rustc_index::bit_set::BitSet diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ac36b940725..9f1ffabc4f8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2103,11 +2103,9 @@ impl<'tcx> TyCtxt<'tcx> { } /// Returns the origin of the opaque type `def_id`. - #[track_caller] - pub fn opaque_type_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin { - let origin = self.hir().expect_opaque_ty(def_id).origin; - trace!("opaque_type_origin({def_id:?}) => {origin:?}"); - origin + #[instrument(skip(self), level = "trace", ret)] + pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin { + self.hir().expect_opaque_ty(def_id).origin } } diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 43bdce5b576..7c280bc8b49 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -94,6 +94,7 @@ trivially_parameterized_over_tcx! { rustc_hir::def_id::DefId, rustc_hir::def_id::DefIndex, rustc_hir::definitions::DefKey, + rustc_hir::OpaqueTyOrigin, rustc_index::bit_set::BitSet, rustc_index::bit_set::FiniteBitSet, rustc_session::cstore::ForeignModule, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 0cf7c43beb5..b97f3dc303b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -384,7 +384,10 @@ impl Trait for X { | DefKind::AssocFn | DefKind::AssocConst ) - && tcx.is_type_alias_impl_trait(opaque_ty.def_id) + && matches!( + tcx.opaque_ty_origin(opaque_ty.def_id), + hir::OpaqueTyOrigin::TyAlias { .. } + ) && !tcx .opaque_types_defined_by(body_owner_def_id.expect_local()) .contains(&opaque_ty.def_id.expect_local()) 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 612e92ea784..7aa558cfd3f 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 @@ -2648,7 +2648,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation: &PredicateObligation<'tcx>, def_id: DefId, ) -> ErrorGuaranteed { - let name = match self.tcx.opaque_type_origin(def_id.expect_local()) { + let name = match self.tcx.local_opaque_ty_origin(def_id.expect_local()) { hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } => { "opaque type".to_string() } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index f177b609485..88d81cfa377 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -246,7 +246,7 @@ fn associated_type_for_impl_trait_in_trait( ) -> LocalDefId { let (hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. }) = - tcx.opaque_type_origin(opaque_ty_def_id) + tcx.local_opaque_ty_origin(opaque_ty_def_id) else { bug!("expected opaque for {opaque_ty_def_id:?}"); }; @@ -284,8 +284,6 @@ fn associated_type_for_impl_trait_in_trait( // Copy defaultness of the containing function. trait_assoc_ty.defaultness(tcx.defaultness(fn_def_id)); - trait_assoc_ty.is_type_alias_impl_trait(false); - // There are no inferred outlives for the synthesized associated type. trait_assoc_ty.inferred_outlives_of(&[]); diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 5e2232ff47d..34f461aac58 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -139,7 +139,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { } // TAITs outside their defining scopes are ignored. - let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local()); + let origin = self.tcx.local_opaque_ty_origin(alias_ty.def_id.expect_local()); trace!(?origin); match origin { rustc_hir::OpaqueTyOrigin::FnReturn { .. }