diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index add88491f8467..acf93c9fc512d 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -484,6 +484,14 @@ impl Key for Option { } } +impl Key for (DefId, Symbol) { + type Cache = DefaultCache; + + fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} + /// Canonical query goals correspond to abstract trait operations that /// are not tied to any crate in particular. impl<'tcx, T: Clone> Key for Canonical<'tcx, T> { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d40a783358959..7400a72a2e72a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1226,6 +1226,12 @@ rustc_queries! { separate_provide_extern } + /// This query backs the [`TyCtxt::has_attr`] function to make it faster. + /// You should use that function instead. + query has_attr_query(key: (DefId, Symbol)) -> bool { + desc { |tcx| "checking whether `{}` has attr {}", tcx.def_path_str(key.0), key.1 } + } + /// Determines whether an item is annotated with `doc(hidden)`. query is_doc_hidden(def_id: DefId) -> bool { desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7d57d88f40f4a..d1e2994d9f5f1 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1801,7 +1801,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Determines whether an item is annotated with an attribute. pub fn has_attr(self, did: impl Into, attr: Symbol) -> bool { - self.get_attrs(did, attr).next().is_some() + self.has_attr_query((did.into(), attr)) } /// Determines whether an item is annotated with a multi-segement attribute diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 9307e38068128..a1cebbc600fd9 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -19,7 +19,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_index::bit_set::GrowableBitSet; use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable}; use rustc_session::Limit; -use rustc_span::sym; +use rustc_span::{sym, Symbol}; use rustc_target::abi::{Float, Integer, IntegerType, Size}; use rustc_target::spec::abi::Abi; use smallvec::{smallvec, SmallVec}; @@ -1829,6 +1829,12 @@ pub fn reveal_opaque_types_in_bounds<'tcx>( val.fold_with(&mut visitor) } +/// Determines whether an item is annotated with an attribute. +pub fn has_attr_query(tcx: TyCtxt<'_>, key: (DefId, Symbol)) -> bool { + let (did, attr) = key; + tcx.get_attrs(did, attr).next().is_some() +} + /// Determines whether an item is directly annotated with `doc(hidden)`. fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { tcx.get_attrs(def_id, sym::doc) @@ -1865,6 +1871,7 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option