don't encode only locally used attrs
This commit is contained in:
parent
87fd70c107
commit
74b6d296db
5 changed files with 54 additions and 16 deletions
|
@ -147,6 +147,16 @@ pub enum AttributeDuplicates {
|
|||
FutureWarnPreceding,
|
||||
}
|
||||
|
||||
/// A conveniece macro to deal with `$($expr)?`.
|
||||
macro_rules! or_default {
|
||||
($default:expr,) => {
|
||||
$default
|
||||
};
|
||||
($default:expr, $next:expr) => {
|
||||
$next
|
||||
};
|
||||
}
|
||||
|
||||
/// A convenience macro for constructing attribute templates.
|
||||
/// E.g., `template!(Word, List: "description")` means that the attribute
|
||||
/// supports forms `#[attr]` and `#[attr(description)]`.
|
||||
|
@ -168,9 +178,10 @@ macro_rules! template {
|
|||
}
|
||||
|
||||
macro_rules! ungated {
|
||||
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr $(,)?) => {
|
||||
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr $(, @only_local: $only_local:expr)? $(,)?) => {
|
||||
BuiltinAttribute {
|
||||
name: sym::$attr,
|
||||
only_local: or_default!(false, $($only_local)?),
|
||||
type_: $typ,
|
||||
template: $tpl,
|
||||
gate: Ungated,
|
||||
|
@ -180,18 +191,20 @@ macro_rules! ungated {
|
|||
}
|
||||
|
||||
macro_rules! gated {
|
||||
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $gate:ident, $msg:expr $(,)?) => {
|
||||
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr $(, @only_local: $only_local:expr)?, $gate:ident, $msg:expr $(,)?) => {
|
||||
BuiltinAttribute {
|
||||
name: sym::$attr,
|
||||
only_local: or_default!(false, $($only_local)?),
|
||||
type_: $typ,
|
||||
template: $tpl,
|
||||
duplicates: $duplicates,
|
||||
gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)),
|
||||
}
|
||||
};
|
||||
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $msg:expr $(,)?) => {
|
||||
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr $(, @only_local: $only_local:expr)?, $msg:expr $(,)?) => {
|
||||
BuiltinAttribute {
|
||||
name: sym::$attr,
|
||||
only_local: or_default!(false, $($only_local)?),
|
||||
type_: $typ,
|
||||
template: $tpl,
|
||||
duplicates: $duplicates,
|
||||
|
@ -201,12 +214,13 @@ macro_rules! gated {
|
|||
}
|
||||
|
||||
macro_rules! rustc_attr {
|
||||
(TEST, $attr:ident, $typ:expr, $tpl:expr, $duplicate:expr $(,)?) => {
|
||||
(TEST, $attr:ident, $typ:expr, $tpl:expr, $duplicate:expr $(, @only_local: $only_local:expr)? $(,)?) => {
|
||||
rustc_attr!(
|
||||
$attr,
|
||||
$typ,
|
||||
$tpl,
|
||||
$duplicate,
|
||||
$(@only_local: $only_local,)?
|
||||
concat!(
|
||||
"the `#[",
|
||||
stringify!($attr),
|
||||
|
@ -215,9 +229,10 @@ macro_rules! rustc_attr {
|
|||
),
|
||||
)
|
||||
};
|
||||
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $msg:expr $(,)?) => {
|
||||
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr $(, @only_local: $only_local:expr)?, $msg:expr $(,)?) => {
|
||||
BuiltinAttribute {
|
||||
name: sym::$attr,
|
||||
only_local: or_default!(false, $($only_local)?),
|
||||
type_: $typ,
|
||||
template: $tpl,
|
||||
duplicates: $duplicates,
|
||||
|
@ -237,6 +252,10 @@ const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never b
|
|||
|
||||
pub struct BuiltinAttribute {
|
||||
pub name: Symbol,
|
||||
/// Whether this attribute is only used in the local crate.
|
||||
///
|
||||
/// If so, it is not encoded in the crate metadata.
|
||||
pub only_local: bool,
|
||||
pub type_: AttributeType,
|
||||
pub template: AttributeTemplate,
|
||||
pub duplicates: AttributeDuplicates,
|
||||
|
@ -295,7 +314,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
ungated!(must_use, Normal, template!(Word, NameValueStr: "reason"), FutureWarnFollowing),
|
||||
gated!(
|
||||
must_not_suspend, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing,
|
||||
must_not_suspend, experimental!(must_not_suspend)
|
||||
experimental!(must_not_suspend)
|
||||
),
|
||||
ungated!(
|
||||
deprecated, Normal,
|
||||
|
@ -394,6 +413,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
// Plugins:
|
||||
BuiltinAttribute {
|
||||
name: sym::plugin,
|
||||
only_local: false,
|
||||
type_: CrateLevel,
|
||||
template: template!(List: "name"),
|
||||
duplicates: DuplicatesOk,
|
||||
|
@ -475,7 +495,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
),
|
||||
// DuplicatesOk since it has its own validation
|
||||
ungated!(
|
||||
stable, Normal, template!(List: r#"feature = "name", since = "version""#), DuplicatesOk
|
||||
stable, Normal, template!(List: r#"feature = "name", since = "version""#), DuplicatesOk,
|
||||
),
|
||||
ungated!(
|
||||
unstable, Normal,
|
||||
|
@ -633,7 +653,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
// Internal attributes, Misc:
|
||||
// ==========================================================================
|
||||
gated!(
|
||||
lang, Normal, template!(NameValueStr: "name"), DuplicatesOk, lang_items,
|
||||
lang, Normal, template!(NameValueStr: "name"), DuplicatesOk, @only_local: true, lang_items,
|
||||
"language items are subject to change",
|
||||
),
|
||||
rustc_attr!(
|
||||
|
@ -642,11 +662,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
"#[rustc_pass_by_value] is used to mark types that must be passed by value instead of reference."
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing,
|
||||
rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing, @only_local: true,
|
||||
"#![rustc_coherence_is_core] allows inherent methods on builtin types, only intended to be used in `core`."
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing,
|
||||
rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: true,
|
||||
"#[rustc_allow_incoherent_impl] has to be added to all impl items of an incoherent inherent impl."
|
||||
),
|
||||
rustc_attr!(
|
||||
|
@ -656,6 +676,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
),
|
||||
BuiltinAttribute {
|
||||
name: sym::rustc_diagnostic_item,
|
||||
// FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`.
|
||||
only_local: false,
|
||||
type_: Normal,
|
||||
template: template!(NameValueStr: "name"),
|
||||
duplicates: ErrorFollowing,
|
||||
|
@ -676,7 +698,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
"unboxed_closures are still evolving",
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_inherit_overflow_checks, Normal, template!(Word), WarnFollowing,
|
||||
rustc_inherit_overflow_checks, Normal, template!(Word), WarnFollowing, @only_local: true,
|
||||
"the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
|
||||
overflow checking behavior of several libcore functions that are inlined \
|
||||
across crates and will never be stable",
|
||||
|
@ -778,6 +800,10 @@ pub fn is_builtin_attr_name(name: Symbol) -> bool {
|
|||
BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
|
||||
}
|
||||
|
||||
pub fn is_builtin_only_local(name: Symbol) -> bool {
|
||||
BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| attr.only_local)
|
||||
}
|
||||
|
||||
pub static BUILTIN_ATTRIBUTE_MAP: SyncLazy<FxHashMap<Symbol, &BuiltinAttribute>> =
|
||||
SyncLazy::new(|| {
|
||||
let mut map = FxHashMap::default();
|
||||
|
|
|
@ -149,7 +149,8 @@ pub use accepted::ACCEPTED_FEATURES;
|
|||
pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES};
|
||||
pub use builtin_attrs::AttributeDuplicates;
|
||||
pub use builtin_attrs::{
|
||||
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, AttributeGate, AttributeTemplate,
|
||||
AttributeType, BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
|
||||
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local,
|
||||
AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute, GatedCfg,
|
||||
BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
|
||||
};
|
||||
pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
|
||||
|
|
|
@ -986,9 +986,13 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
|
|||
|
||||
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
fn encode_attrs(&mut self, def_id: DefId) {
|
||||
let attrs = self.tcx.get_attrs(def_id);
|
||||
record!(self.tables.attributes[def_id] <- attrs);
|
||||
if attrs.iter().any(|attr| attr.may_have_doc_links()) {
|
||||
let mut attrs = self
|
||||
.tcx
|
||||
.get_attrs(def_id)
|
||||
.iter()
|
||||
.filter(|attr| !rustc_feature::is_builtin_only_local(attr.name_or_empty()));
|
||||
record!(self.tables.attributes[def_id] <- attrs.clone());
|
||||
if attrs.any(|attr| attr.may_have_doc_links()) {
|
||||
self.tables.may_have_doc_links.set(def_id.index, ());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1072,6 +1072,9 @@ rustc_queries! {
|
|||
desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) }
|
||||
}
|
||||
|
||||
/// Returns the attributes on the item at `def_id`.
|
||||
///
|
||||
/// Do not use this directly, use `tcx.get_attrs` instead.
|
||||
query item_attrs(def_id: DefId) -> &'tcx [ast::Attribute] {
|
||||
desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) }
|
||||
separate_provide_extern
|
||||
|
|
|
@ -2187,6 +2187,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
/// Gets the attributes of a definition.
|
||||
///
|
||||
/// Note that attributes which are be relevant while
|
||||
/// the current local crate are not stored in the crate metadata
|
||||
/// and therefore cannot be accessed outside of that crate.
|
||||
pub fn get_attrs(self, did: DefId) -> Attributes<'tcx> {
|
||||
if let Some(did) = did.as_local() {
|
||||
self.hir().attrs(self.hir().local_def_id_to_hir_id(did))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue