From fe58a05d076f444f34006413734373771c782de8 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 14 Mar 2025 14:51:40 +0000 Subject: [PATCH] Add a per-item query just for `define_opaque` attributes --- compiler/rustc_ast_lowering/src/lib.rs | 4 ++-- compiler/rustc_hir/src/hir.rs | 16 +++++++++------- compiler/rustc_hir/src/stable_hash_impls.rs | 2 +- compiler/rustc_middle/src/hir/mod.rs | 5 +++++ compiler/rustc_middle/src/query/mod.rs | 3 +++ compiler/rustc_ty_utils/src/opaque_types.rs | 6 +++--- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c7d37e2704de9..cc5eab895fbb9 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -625,9 +625,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let num_nodes = self.item_local_id_counter.as_usize(); let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes); let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies }; - let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque }; + let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash }; - self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map }) + self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map, define_opaque }) } /// This method allocates a new `HirId` for the given `NodeId`. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5cf231d566828..44ab63f6ad9fd 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1307,18 +1307,13 @@ impl Attribute { #[derive(Debug)] pub struct AttributeMap<'tcx> { pub map: SortedMap, - /// Preprocessed `#[define_opaque]` attribute. - pub define_opaque: Option<&'tcx [(Span, LocalDefId)]>, // Only present when the crate hash is needed. pub opt_hash: Option, } impl<'tcx> AttributeMap<'tcx> { - pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap { - map: SortedMap::new(), - opt_hash: Some(Fingerprint::ZERO), - define_opaque: None, - }; + pub const EMPTY: &'static AttributeMap<'static> = + &AttributeMap { map: SortedMap::new(), opt_hash: Some(Fingerprint::ZERO) }; #[inline] pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] { @@ -1382,6 +1377,13 @@ pub struct OwnerInfo<'hir> { /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. pub trait_map: ItemLocalMap>, + /// Preprocessed `#[define_opaque]` attribute. + /// `None` means there was no attribute. + /// `Some(&[])` means there was an attribute, but it had no entries. + /// This can be used to remove the opaques defined by default, e.g. on + /// associated methods which automatically pick up opaques in associated types + /// if they mention that associated type in their signature. + pub define_opaque: Option<&'hir [(Span, LocalDefId)]>, } impl<'tcx> OwnerInfo<'tcx> { diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 91ea88cae4776..2709a826549c5 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -106,7 +106,7 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable for AttributeMap fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) { // We ignore the `map` since it refers to information included in `opt_hash` which is // hashed in the collector and used for the crate hash. - let AttributeMap { opt_hash, define_opaque: _, map: _ } = *self; + let AttributeMap { opt_hash, map: _ } = *self; opt_hash.unwrap().hash_stable(hcx, hasher); } } diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 68b9a4f56b96d..9d862d7866d49 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -238,4 +238,9 @@ pub fn provide(providers: &mut Providers) { providers.in_scope_traits_map = |tcx, id| { tcx.hir_crate(()).owners[id.def_id].as_owner().map(|owner_info| &owner_info.trait_map) }; + providers.explicitly_defined_opaques = |tcx, id| { + tcx.hir_crate(()).owners[id.def_id] + .as_owner() + .and_then(|owner_info| Some(*owner_info.define_opaque.as_ref()?)) + }; } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 94a5a3769a322..cac89eb1f31f8 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1724,6 +1724,9 @@ rustc_queries! { -> Option<&'tcx ItemLocalMap>> { desc { "getting traits in scope at a block" } } + query explicitly_defined_opaques(_: hir::OwnerId) -> Option<&'tcx [(Span, LocalDefId)]> { + desc { "getting the explicitly defined opaque types"} + } /// Returns whether the impl or associated function has the `default` keyword. query defaultness(def_id: DefId) -> hir::Defaultness { diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 3aad97d86cca1..43a84c21d094d 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -184,10 +184,10 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { #[instrument(level = "trace", skip(self))] fn collect_taits_from_defines_attr(&mut self) { let hir_id = self.tcx.local_def_id_to_hir_id(self.item); - if !hir_id.is_owner() { + let Some(owner_id) = hir_id.as_owner() else { return; - } - let Some(defines) = self.tcx.hir_attr_map(hir_id.owner).define_opaque else { + }; + let Some(defines) = self.tcx.explicitly_defined_opaques(owner_id) else { return; }; for &(span, define) in defines {