Rename KNOWN_ATTRS to BUILT_ATTRS, and create KNOWN_ATTRS
KNOWN_ATTRIBUTES should really be named BUILT_ATTRIBUTES, while KNOWN_ATTRIBUTES should be used to mark attributes as known, similar to USED_ATTRIBUTES.
This commit is contained in:
parent
cae6ab1c45
commit
d377cf5b3f
3 changed files with 34 additions and 8 deletions
|
@ -19,7 +19,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
|
|||
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
|
||||
use syntax::feature_gate::{BUILTIN_ATTRIBUTES, AttributeType};
|
||||
use syntax::parse::token::keywords;
|
||||
use syntax::ptr::P;
|
||||
use syntax_pos::Span;
|
||||
|
@ -245,7 +245,7 @@ impl LateLintPass for UnusedAttributes {
|
|||
debug!("checking attribute: {:?}", attr);
|
||||
|
||||
// Note that check_name() marks the attribute as used if it matches.
|
||||
for &(ref name, ty, _) in KNOWN_ATTRIBUTES {
|
||||
for &(ref name, ty, _) in BUILTIN_ATTRIBUTES {
|
||||
match ty {
|
||||
AttributeType::Whitelisted if attr.check_name(name) => {
|
||||
debug!("{:?} is Whitelisted", name);
|
||||
|
@ -267,7 +267,7 @@ impl LateLintPass for UnusedAttributes {
|
|||
debug!("Emitting warning for: {:?}", attr);
|
||||
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
|
||||
// Is it a builtin attribute that must be used at the crate level?
|
||||
let known_crate = KNOWN_ATTRIBUTES.iter()
|
||||
let known_crate = BUILTIN_ATTRIBUTES.iter()
|
||||
.find(|&&(name, ty, _)| attr.name() == name && ty == AttributeType::CrateLevel)
|
||||
.is_some();
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ use std::cell::{RefCell, Cell};
|
|||
use std::collections::HashSet;
|
||||
|
||||
thread_local! {
|
||||
static USED_ATTRS: RefCell<Vec<u64>> = RefCell::new(Vec::new())
|
||||
static USED_ATTRS: RefCell<Vec<u64>> = RefCell::new(Vec::new());
|
||||
static KNOWN_ATTRS: RefCell<Vec<u64>> = RefCell::new(Vec::new());
|
||||
}
|
||||
|
||||
enum AttrError {
|
||||
|
@ -81,6 +82,29 @@ pub fn is_used(attr: &Attribute) -> bool {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn mark_known(attr: &Attribute) {
|
||||
debug!("Marking {:?} as known.", attr);
|
||||
let AttrId(id) = attr.node.id;
|
||||
KNOWN_ATTRS.with(|slot| {
|
||||
let idx = (id / 64) as usize;
|
||||
let shift = id % 64;
|
||||
if slot.borrow().len() <= idx {
|
||||
slot.borrow_mut().resize(idx + 1, 0);
|
||||
}
|
||||
slot.borrow_mut()[idx] |= 1 << shift;
|
||||
});
|
||||
}
|
||||
|
||||
pub fn is_known(attr: &Attribute) -> bool {
|
||||
let AttrId(id) = attr.node.id;
|
||||
KNOWN_ATTRS.with(|slot| {
|
||||
let idx = (id / 64) as usize;
|
||||
let shift = id % 64;
|
||||
slot.borrow().get(idx).map(|bits| bits & (1 << shift) != 0)
|
||||
.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
impl NestedMetaItem {
|
||||
/// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem.
|
||||
pub fn meta_item(&self) -> Option<&P<MetaItem>> {
|
||||
|
|
|
@ -417,11 +417,11 @@ macro_rules! cfg_fn {
|
|||
}
|
||||
|
||||
pub fn deprecated_attributes() -> Vec<&'static (&'static str, AttributeType, AttributeGate)> {
|
||||
KNOWN_ATTRIBUTES.iter().filter(|a| a.2.is_deprecated()).collect()
|
||||
BUILTIN_ATTRIBUTES.iter().filter(|a| a.2.is_deprecated()).collect()
|
||||
}
|
||||
|
||||
// Attributes that have a special meaning to rustc or rustdoc
|
||||
pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGate)] = &[
|
||||
pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGate)] = &[
|
||||
// Normal attributes
|
||||
|
||||
("warn", Normal, Ungated),
|
||||
|
@ -790,12 +790,12 @@ impl<'a> Context<'a> {
|
|||
fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) {
|
||||
debug!("check_attribute(attr = {:?})", attr);
|
||||
let name = &*attr.name();
|
||||
for &(n, ty, ref gateage) in KNOWN_ATTRIBUTES {
|
||||
for &(n, ty, ref gateage) in BUILTIN_ATTRIBUTES {
|
||||
if n == name {
|
||||
if let &Gated(_, ref name, ref desc, ref has_feature) = gateage {
|
||||
gate_feature_fn!(self, has_feature, attr.span, name, desc);
|
||||
}
|
||||
debug!("check_attribute: {:?} is known, {:?}, {:?}", name, ty, gateage);
|
||||
debug!("check_attribute: {:?} is builtin, {:?}, {:?}", name, ty, gateage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -815,6 +815,8 @@ impl<'a> Context<'a> {
|
|||
are reserved for internal compiler diagnostics");
|
||||
} else if name.starts_with("derive_") {
|
||||
gate_feature!(self, custom_derive, attr.span, EXPLAIN_DERIVE_UNDERSCORE);
|
||||
} else if attr::is_known(attr) {
|
||||
debug!("check_attribute: {:?} is known", name);
|
||||
} else {
|
||||
// Only run the custom attribute lint during regular
|
||||
// feature gate checking. Macro gating runs
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue