diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f4f243151ee..09f4f34b98d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -80,12 +80,8 @@ First, create a new UI test file in the `tests/ui/` directory with the pattern y ```rust // ./tests/ui/my_lint.rs - -// The custom_attribute needs to be enabled for the author lint to work -#![feature(plugin, custom_attribute)] - fn main() { - #[clippy(author)] + #[clippy::author] let arr: [i32; 1] = [7]; // Replace line with the code you want to match } ``` diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 821093735df..7864e90c196 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1,7 +1,6 @@ // error-pattern:cargo-clippy #![feature(box_syntax)] -#![feature(custom_attribute)] #![feature(rustc_private)] #![feature(slice_patterns)] #![feature(stmt_expr_attributes)] diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index d3a0d5b2c9e..dd43a0d2177 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -7,8 +7,9 @@ use rustc::lint::*; use rustc::hir; use rustc::hir::{Expr, Expr_, QPath, Ty_, Pat, PatKind, BindingAnnotation, StmtSemi, StmtExpr, StmtDecl, Decl_, Stmt}; use rustc::hir::intravisit::{NestedVisitorMap, Visitor}; -use syntax::ast::{self, Attribute, LitKind, DUMMY_NODE_ID}; +use syntax::ast::{Attribute, LitKind, DUMMY_NODE_ID}; use std::collections::HashMap; +use utils::get_attr; /// **What it does:** Generates clippy code that detects the offending pattern /// @@ -17,10 +18,10 @@ use std::collections::HashMap; /// // ./tests/ui/my_lint.rs /// fn foo() { /// // detect the following pattern -/// #[clippy(author)] +/// #[clippy::author] /// if x == 42 { /// // but ignore everything from here on -/// #![clippy(author = "ignore")] +/// #![clippy::author = "ignore"] /// } /// } /// ``` @@ -633,14 +634,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { } fn has_attr(attrs: &[Attribute]) -> bool { - attrs.iter().any(|attr| { - attr.check_name("clippy") && attr.meta_item_list().map_or(false, |list| { - list.len() == 1 && match list[0].node { - ast::NestedMetaItemKind::MetaItem(ref it) => it.name() == "author", - ast::NestedMetaItemKind::Literal(_) => false, - } - }) - }) + get_attr(attrs, "author").count() > 0 } fn desugaring_name(des: hir::MatchSource) -> String { diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index b5bb3fd2e21..10a9a3a03c1 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -6,7 +6,7 @@ use rustc::lint::*; use rustc::hir; use rustc::hir::print; use syntax::ast::Attribute; -use syntax::attr; +use utils::get_attr; /// **What it does:** Dumps every ast/hir node which has the `#[clippy_dump]` /// attribute @@ -136,7 +136,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } fn has_attr(attrs: &[Attribute]) -> bool { - attr::contains_name(attrs, "clippy_dump") + get_attr(attrs, "dump").count() > 0 } fn print_decl(cx: &LateContext, decl: &hir::Decl) { diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index e656ea5cba2..d5c7796fac6 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -735,20 +735,26 @@ impl LimitStack { } } -fn parse_attrs(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) { - for attr in attrs { - if attr.is_sugared_doc { - continue; +pub fn get_attr<'a>(attrs: &'a [ast::Attribute], name: &'static str) -> impl Iterator { + attrs.iter().filter_map(move |attr| { + if attr.path.segments.len() == 2 && attr.path.segments[0].ident.to_string() == "clippy" && attr.path.segments[1].ident.to_string() == name { + Some(attr) + } else { + None } + }) +} + +fn parse_attrs(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) { + for attr in get_attr(attrs, name) { if let Some(ref value) = attr.value_str() { - if attr.name() == name { - if let Ok(value) = FromStr::from_str(&value.as_str()) { - attr::mark_used(attr); - f(value) - } else { - sess.span_err(attr.span, "not a number"); - } + if let Ok(value) = FromStr::from_str(&value.as_str()) { + f(value) + } else { + sess.span_err(attr.span, "not a number"); } + } else { + sess.span_err(attr.span, "bad clippy attribute"); } } } diff --git a/tests/ui/author.rs b/tests/ui/author.rs index 3a819872bc5..eec26bcce3c 100644 --- a/tests/ui/author.rs +++ b/tests/ui/author.rs @@ -1,7 +1,7 @@ -#![feature(plugin, custom_attribute)] +#![feature(tool_attributes)] fn main() { - #[clippy(author)] + #[clippy::author] let x: char = 0x45 as char; } diff --git a/tests/ui/author/for_loop.rs b/tests/ui/author/for_loop.rs index 657bf51bf80..5faf440676d 100644 --- a/tests/ui/author/for_loop.rs +++ b/tests/ui/author/for_loop.rs @@ -1,7 +1,7 @@ -#![feature(custom_attribute)] +#![feature(tool_attributes)] fn main() { - #[clippy(author)] + #[clippy::author] for y in 0..10 { let z = y; } diff --git a/tests/ui/author/matches.rs b/tests/ui/author/matches.rs index f426302da09..e6bf229103f 100644 --- a/tests/ui/author/matches.rs +++ b/tests/ui/author/matches.rs @@ -1,7 +1,7 @@ -#![feature(custom_attribute)] +#![feature(tool_attributes)] fn main() { - #[clippy(author)] + #[clippy::author] let a = match 42 { 16 => 5, 17 => { diff --git a/tests/ui/cyclomatic_complexity.rs b/tests/ui/cyclomatic_complexity.rs index 1afae69c186..3214505ba1e 100644 --- a/tests/ui/cyclomatic_complexity.rs +++ b/tests/ui/cyclomatic_complexity.rs @@ -1,4 +1,4 @@ -#![feature(custom_attribute)] +#![feature(tool_attributes)] #![allow(clippy)] #![warn(cyclomatic_complexity)] @@ -88,7 +88,7 @@ fn main() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn kaboom() { let n = 0; 'a: for i in 0..20 { @@ -134,17 +134,17 @@ fn bloo() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn lots_of_short_circuits() -> bool { true && false && true && false && true && false && true } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn lots_of_short_circuits2() -> bool { true || false || true || false || true || false || true } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn baa() { let x = || match 99 { 0 => 0, @@ -162,7 +162,7 @@ fn baa() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn bar() { match 99 { 0 => println!("hi"), @@ -171,7 +171,7 @@ fn bar() { } #[test] -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] /// Tests are usually complex but simple at the same time. `cyclomatic_complexity` used to give /// lots of false-positives in tests. fn dont_warn_on_tests() { @@ -181,7 +181,7 @@ fn dont_warn_on_tests() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn barr() { match 99 { 0 => println!("hi"), @@ -191,7 +191,7 @@ fn barr() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn barr2() { match 99 { 0 => println!("hi"), @@ -207,7 +207,7 @@ fn barr2() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn barrr() { match 99 { 0 => println!("hi"), @@ -217,7 +217,7 @@ fn barrr() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn barrr2() { match 99 { 0 => println!("hi"), @@ -233,7 +233,7 @@ fn barrr2() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn barrrr() { match 99 { 0 => println!("hi"), @@ -243,7 +243,7 @@ fn barrrr() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn barrrr2() { match 99 { 0 => println!("hi"), @@ -259,7 +259,7 @@ fn barrrr2() { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn cake() { if 4 == 5 { println!("yea"); @@ -270,7 +270,7 @@ fn cake() { } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] pub fn read_file(input_path: &str) -> String { use std::fs::File; use std::io::{Read, Write}; @@ -301,7 +301,7 @@ pub fn read_file(input_path: &str) -> String { enum Void {} -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn void(void: Void) { if true { match void { @@ -309,13 +309,13 @@ fn void(void: Void) { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn mcarton_sees_all() { panic!("meh"); panic!("möh"); } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn try() -> Result { match 5 { 5 => Ok(5), @@ -323,7 +323,7 @@ fn try() -> Result { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn try_again() -> Result { let _ = try!(Ok(42)); let _ = try!(Ok(43)); @@ -339,7 +339,7 @@ fn try_again() -> Result { } } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn early() -> Result { return Ok(5); return Ok(5); @@ -352,7 +352,7 @@ fn early() -> Result { return Ok(5); } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn early_ret() -> i32 { let a = if true { 42 } else { return 0; }; let a = if a < 99 { 42 } else { return 0; }; diff --git a/tests/ui/cyclomatic_complexity_attr_used.rs b/tests/ui/cyclomatic_complexity_attr_used.rs index f3895c7e3ab..50b19f9d7ba 100644 --- a/tests/ui/cyclomatic_complexity_attr_used.rs +++ b/tests/ui/cyclomatic_complexity_attr_used.rs @@ -1,4 +1,4 @@ -#![feature(custom_attribute)] +#![feature(tool_attributes)] #![warn(cyclomatic_complexity)] #![warn(unused)] @@ -7,7 +7,7 @@ fn main() { kaboom(); } -#[cyclomatic_complexity = "0"] +#[clippy::cyclomatic_complexity = "0"] fn kaboom() { if 42 == 43 { panic!(); diff --git a/tests/ui/excessive_precision.rs b/tests/ui/excessive_precision.rs index 25b6555715f..c17639aaf04 100644 --- a/tests/ui/excessive_precision.rs +++ b/tests/ui/excessive_precision.rs @@ -1,4 +1,4 @@ -#![feature(custom_attribute)] + #![warn(excessive_precision)] #![allow(print_literal)] diff --git a/tests/ui/for_loop.rs b/tests/ui/for_loop.rs index ce776d4d91c..e28a8f1e178 100644 --- a/tests/ui/for_loop.rs +++ b/tests/ui/for_loop.rs @@ -1,4 +1,4 @@ -#![feature(custom_attribute)] + use std::collections::*; diff --git a/tests/ui/trailing_zeros.rs b/tests/ui/trailing_zeros.rs index d915a0bed09..5494e780628 100644 --- a/tests/ui/trailing_zeros.rs +++ b/tests/ui/trailing_zeros.rs @@ -1,10 +1,10 @@ -#![feature(custom_attribute, stmt_expr_attributes)] +#![feature(stmt_expr_attributes, tool_attributes)] #![allow(unused_parens)] fn main() { let x: i32 = 42; - let _ = #[clippy(author)] (x & 0b1111 == 0); // suggest trailing_zeros + let _ = #[clippy::author] (x & 0b1111 == 0); // suggest trailing_zeros let _ = x & 0b1_1111 == 0; // suggest trailing_zeros let _ = x & 0b1_1010 == 0; // do not lint let _ = x & 1 == 0; // do not lint diff --git a/tests/ui/trailing_zeros.stderr b/tests/ui/trailing_zeros.stderr index 91e4d59da98..47b46be9ba8 100644 --- a/tests/ui/trailing_zeros.stderr +++ b/tests/ui/trailing_zeros.stderr @@ -1,7 +1,7 @@ error: bit mask could be simplified with a call to `trailing_zeros` --> $DIR/trailing_zeros.rs:7:31 | -7 | let _ = #[clippy(author)] (x & 0b1111 == 0); // suggest trailing_zeros +7 | let _ = #[clippy::author] (x & 0b1111 == 0); // suggest trailing_zeros | ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 4` | = note: `-D verbose-bit-mask` implied by `-D warnings`