44 lines
1.9 KiB
Rust
44 lines
1.9 KiB
Rust
use rustc_ast::{Attribute, MetaItem};
|
|
use rustc_expand::base::{Annotatable, ExtCtxt};
|
|
use rustc_feature::AttributeTemplate;
|
|
use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES;
|
|
use rustc_parse::validate_attr;
|
|
use rustc_span::Symbol;
|
|
|
|
pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) {
|
|
// All the built-in macro attributes are "words" at the moment.
|
|
let template = AttributeTemplate { word: true, ..Default::default() };
|
|
let attr = ecx.attribute(meta_item.clone());
|
|
validate_attr::check_builtin_attribute(&ecx.sess.parse_sess, &attr, name, template);
|
|
}
|
|
|
|
/// Emit a warning if the item is annotated with the given attribute. This is used to diagnose when
|
|
/// an attribute may have been mistakenly duplicated.
|
|
pub fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: Symbol) {
|
|
let attrs: Option<&[Attribute]> = match item {
|
|
Annotatable::Item(item) => Some(&item.attrs),
|
|
Annotatable::TraitItem(item) => Some(&item.attrs),
|
|
Annotatable::ImplItem(item) => Some(&item.attrs),
|
|
Annotatable::ForeignItem(item) => Some(&item.attrs),
|
|
Annotatable::Expr(expr) => Some(&expr.attrs),
|
|
Annotatable::Arm(arm) => Some(&arm.attrs),
|
|
Annotatable::ExprField(field) => Some(&field.attrs),
|
|
Annotatable::PatField(field) => Some(&field.attrs),
|
|
Annotatable::GenericParam(param) => Some(¶m.attrs),
|
|
Annotatable::Param(param) => Some(¶m.attrs),
|
|
Annotatable::FieldDef(def) => Some(&def.attrs),
|
|
Annotatable::Variant(variant) => Some(&variant.attrs),
|
|
_ => None,
|
|
};
|
|
if let Some(attrs) = attrs {
|
|
if let Some(attr) = ecx.sess.find_by_name(attrs, name) {
|
|
ecx.parse_sess().buffer_lint(
|
|
DUPLICATE_MACRO_ATTRIBUTES,
|
|
attr.span,
|
|
ecx.current_expansion.lint_node_id,
|
|
"duplicated attribute",
|
|
);
|
|
}
|
|
}
|
|
}
|