Add a lint for duplicated attributes.
This commit is contained in:
parent
753e569c9c
commit
2be94d4301
8 changed files with 134 additions and 4 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::util::check_builtin_macro_attribute;
|
||||
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::mut_visit::MutVisitor;
|
||||
|
@ -25,6 +25,7 @@ crate fn expand(
|
|||
annotatable: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
check_builtin_macro_attribute(ecx, meta_item, sym::cfg_eval);
|
||||
warn_on_duplicate_attribute(&ecx, &annotatable, sym::cfg_eval);
|
||||
vec![cfg_eval(ecx.sess, ecx.ecfg.features, annotatable)]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/// The expansion from a test function to the appropriate test struct for libtest
|
||||
/// Ideally, this code would be in libtest but for efficiency and error messages it lives here.
|
||||
use crate::util::check_builtin_macro_attribute;
|
||||
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::attr;
|
||||
|
@ -27,6 +27,7 @@ pub fn expand_test_case(
|
|||
anno_item: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
check_builtin_macro_attribute(ecx, meta_item, sym::test_case);
|
||||
warn_on_duplicate_attribute(&ecx, &anno_item, sym::test_case);
|
||||
|
||||
if !ecx.ecfg.should_test {
|
||||
return vec![];
|
||||
|
@ -55,6 +56,7 @@ pub fn expand_test(
|
|||
item: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
check_builtin_macro_attribute(cx, meta_item, sym::test);
|
||||
warn_on_duplicate_attribute(&cx, &item, sym::test);
|
||||
expand_test_or_bench(cx, attr_sp, item, false)
|
||||
}
|
||||
|
||||
|
@ -65,6 +67,7 @@ pub fn expand_bench(
|
|||
item: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
check_builtin_macro_attribute(cx, meta_item, sym::bench);
|
||||
warn_on_duplicate_attribute(&cx, &item, sym::bench);
|
||||
expand_test_or_bench(cx, attr_sp, item, true)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_ast::MetaItem;
|
||||
use rustc_expand::base::ExtCtxt;
|
||||
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;
|
||||
|
||||
|
@ -10,3 +11,33 @@ pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, na
|
|||
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",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue