Use the new scoped tool attributes
This commit is contained in:
@@ -80,12 +80,8 @@ First, create a new UI test file in the `tests/ui/` directory with the pattern y
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
// ./tests/ui/my_lint.rs
|
// ./tests/ui/my_lint.rs
|
||||||
|
|
||||||
// The custom_attribute needs to be enabled for the author lint to work
|
|
||||||
#![feature(plugin, custom_attribute)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[clippy(author)]
|
#[clippy::author]
|
||||||
let arr: [i32; 1] = [7]; // Replace line with the code you want to match
|
let arr: [i32; 1] = [7]; // Replace line with the code you want to match
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// error-pattern:cargo-clippy
|
// error-pattern:cargo-clippy
|
||||||
|
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(custom_attribute)]
|
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![feature(slice_patterns)]
|
#![feature(slice_patterns)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ use rustc::lint::*;
|
|||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::{Expr, Expr_, QPath, Ty_, Pat, PatKind, BindingAnnotation, StmtSemi, StmtExpr, StmtDecl, Decl_, Stmt};
|
use rustc::hir::{Expr, Expr_, QPath, Ty_, Pat, PatKind, BindingAnnotation, StmtSemi, StmtExpr, StmtDecl, Decl_, Stmt};
|
||||||
use rustc::hir::intravisit::{NestedVisitorMap, Visitor};
|
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 std::collections::HashMap;
|
||||||
|
use utils::get_attr;
|
||||||
|
|
||||||
/// **What it does:** Generates clippy code that detects the offending pattern
|
/// **What it does:** Generates clippy code that detects the offending pattern
|
||||||
///
|
///
|
||||||
@@ -17,10 +18,10 @@ use std::collections::HashMap;
|
|||||||
/// // ./tests/ui/my_lint.rs
|
/// // ./tests/ui/my_lint.rs
|
||||||
/// fn foo() {
|
/// fn foo() {
|
||||||
/// // detect the following pattern
|
/// // detect the following pattern
|
||||||
/// #[clippy(author)]
|
/// #[clippy::author]
|
||||||
/// if x == 42 {
|
/// if x == 42 {
|
||||||
/// // but ignore everything from here on
|
/// // 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 {
|
fn has_attr(attrs: &[Attribute]) -> bool {
|
||||||
attrs.iter().any(|attr| {
|
get_attr(attrs, "author").count() > 0
|
||||||
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,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desugaring_name(des: hir::MatchSource) -> String {
|
fn desugaring_name(des: hir::MatchSource) -> String {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use rustc::lint::*;
|
|||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::print;
|
use rustc::hir::print;
|
||||||
use syntax::ast::Attribute;
|
use syntax::ast::Attribute;
|
||||||
use syntax::attr;
|
use utils::get_attr;
|
||||||
|
|
||||||
/// **What it does:** Dumps every ast/hir node which has the `#[clippy_dump]`
|
/// **What it does:** Dumps every ast/hir node which has the `#[clippy_dump]`
|
||||||
/// attribute
|
/// attribute
|
||||||
@@ -136,7 +136,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn has_attr(attrs: &[Attribute]) -> bool {
|
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) {
|
fn print_decl(cx: &LateContext, decl: &hir::Decl) {
|
||||||
|
|||||||
@@ -735,20 +735,26 @@ impl LimitStack {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
|
pub fn get_attr<'a>(attrs: &'a [ast::Attribute], name: &'static str) -> impl Iterator<Item = &'a ast::Attribute> {
|
||||||
for attr in attrs {
|
attrs.iter().filter_map(move |attr| {
|
||||||
if attr.is_sugared_doc {
|
if attr.path.segments.len() == 2 && attr.path.segments[0].ident.to_string() == "clippy" && attr.path.segments[1].ident.to_string() == name {
|
||||||
continue;
|
Some(attr)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_attrs<F: FnMut(u64)>(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 let Some(ref value) = attr.value_str() {
|
||||||
if attr.name() == name {
|
|
||||||
if let Ok(value) = FromStr::from_str(&value.as_str()) {
|
if let Ok(value) = FromStr::from_str(&value.as_str()) {
|
||||||
attr::mark_used(attr);
|
|
||||||
f(value)
|
f(value)
|
||||||
} else {
|
} else {
|
||||||
sess.span_err(attr.span, "not a number");
|
sess.span_err(attr.span, "not a number");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
sess.span_err(attr.span, "bad clippy attribute");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#![feature(plugin, custom_attribute)]
|
#![feature(tool_attributes)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
#[clippy(author)]
|
#[clippy::author]
|
||||||
let x: char = 0x45 as char;
|
let x: char = 0x45 as char;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#![feature(custom_attribute)]
|
#![feature(tool_attributes)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[clippy(author)]
|
#[clippy::author]
|
||||||
for y in 0..10 {
|
for y in 0..10 {
|
||||||
let z = y;
|
let z = y;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#![feature(custom_attribute)]
|
#![feature(tool_attributes)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[clippy(author)]
|
#[clippy::author]
|
||||||
let a = match 42 {
|
let a = match 42 {
|
||||||
16 => 5,
|
16 => 5,
|
||||||
17 => {
|
17 => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![feature(custom_attribute)]
|
#![feature(tool_attributes)]
|
||||||
|
|
||||||
#![allow(clippy)]
|
#![allow(clippy)]
|
||||||
#![warn(cyclomatic_complexity)]
|
#![warn(cyclomatic_complexity)]
|
||||||
@@ -88,7 +88,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn kaboom() {
|
fn kaboom() {
|
||||||
let n = 0;
|
let n = 0;
|
||||||
'a: for i in 0..20 {
|
'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 {
|
fn lots_of_short_circuits() -> bool {
|
||||||
true && false && true && false && true && false && true
|
true && false && true && false && true && false && true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn lots_of_short_circuits2() -> bool {
|
fn lots_of_short_circuits2() -> bool {
|
||||||
true || false || true || false || true || false || true
|
true || false || true || false || true || false || true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn baa() {
|
fn baa() {
|
||||||
let x = || match 99 {
|
let x = || match 99 {
|
||||||
0 => 0,
|
0 => 0,
|
||||||
@@ -162,7 +162,7 @@ fn baa() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn bar() {
|
fn bar() {
|
||||||
match 99 {
|
match 99 {
|
||||||
0 => println!("hi"),
|
0 => println!("hi"),
|
||||||
@@ -171,7 +171,7 @@ fn bar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
/// Tests are usually complex but simple at the same time. `cyclomatic_complexity` used to give
|
/// Tests are usually complex but simple at the same time. `cyclomatic_complexity` used to give
|
||||||
/// lots of false-positives in tests.
|
/// lots of false-positives in tests.
|
||||||
fn dont_warn_on_tests() {
|
fn dont_warn_on_tests() {
|
||||||
@@ -181,7 +181,7 @@ fn dont_warn_on_tests() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn barr() {
|
fn barr() {
|
||||||
match 99 {
|
match 99 {
|
||||||
0 => println!("hi"),
|
0 => println!("hi"),
|
||||||
@@ -191,7 +191,7 @@ fn barr() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn barr2() {
|
fn barr2() {
|
||||||
match 99 {
|
match 99 {
|
||||||
0 => println!("hi"),
|
0 => println!("hi"),
|
||||||
@@ -207,7 +207,7 @@ fn barr2() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn barrr() {
|
fn barrr() {
|
||||||
match 99 {
|
match 99 {
|
||||||
0 => println!("hi"),
|
0 => println!("hi"),
|
||||||
@@ -217,7 +217,7 @@ fn barrr() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn barrr2() {
|
fn barrr2() {
|
||||||
match 99 {
|
match 99 {
|
||||||
0 => println!("hi"),
|
0 => println!("hi"),
|
||||||
@@ -233,7 +233,7 @@ fn barrr2() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn barrrr() {
|
fn barrrr() {
|
||||||
match 99 {
|
match 99 {
|
||||||
0 => println!("hi"),
|
0 => println!("hi"),
|
||||||
@@ -243,7 +243,7 @@ fn barrrr() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn barrrr2() {
|
fn barrrr2() {
|
||||||
match 99 {
|
match 99 {
|
||||||
0 => println!("hi"),
|
0 => println!("hi"),
|
||||||
@@ -259,7 +259,7 @@ fn barrrr2() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn cake() {
|
fn cake() {
|
||||||
if 4 == 5 {
|
if 4 == 5 {
|
||||||
println!("yea");
|
println!("yea");
|
||||||
@@ -270,7 +270,7 @@ fn cake() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
pub fn read_file(input_path: &str) -> String {
|
pub fn read_file(input_path: &str) -> String {
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
@@ -301,7 +301,7 @@ pub fn read_file(input_path: &str) -> String {
|
|||||||
|
|
||||||
enum Void {}
|
enum Void {}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn void(void: Void) {
|
fn void(void: Void) {
|
||||||
if true {
|
if true {
|
||||||
match void {
|
match void {
|
||||||
@@ -309,13 +309,13 @@ fn void(void: Void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn mcarton_sees_all() {
|
fn mcarton_sees_all() {
|
||||||
panic!("meh");
|
panic!("meh");
|
||||||
panic!("möh");
|
panic!("möh");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn try() -> Result<i32, &'static str> {
|
fn try() -> Result<i32, &'static str> {
|
||||||
match 5 {
|
match 5 {
|
||||||
5 => Ok(5),
|
5 => Ok(5),
|
||||||
@@ -323,7 +323,7 @@ fn try() -> Result<i32, &'static str> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn try_again() -> Result<i32, &'static str> {
|
fn try_again() -> Result<i32, &'static str> {
|
||||||
let _ = try!(Ok(42));
|
let _ = try!(Ok(42));
|
||||||
let _ = try!(Ok(43));
|
let _ = try!(Ok(43));
|
||||||
@@ -339,7 +339,7 @@ fn try_again() -> Result<i32, &'static str> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn early() -> Result<i32, &'static str> {
|
fn early() -> Result<i32, &'static str> {
|
||||||
return Ok(5);
|
return Ok(5);
|
||||||
return Ok(5);
|
return Ok(5);
|
||||||
@@ -352,7 +352,7 @@ fn early() -> Result<i32, &'static str> {
|
|||||||
return Ok(5);
|
return Ok(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn early_ret() -> i32 {
|
fn early_ret() -> i32 {
|
||||||
let a = if true { 42 } else { return 0; };
|
let a = if true { 42 } else { return 0; };
|
||||||
let a = if a < 99 { 42 } else { return 0; };
|
let a = if a < 99 { 42 } else { return 0; };
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![feature(custom_attribute)]
|
#![feature(tool_attributes)]
|
||||||
|
|
||||||
#![warn(cyclomatic_complexity)]
|
#![warn(cyclomatic_complexity)]
|
||||||
#![warn(unused)]
|
#![warn(unused)]
|
||||||
@@ -7,7 +7,7 @@ fn main() {
|
|||||||
kaboom();
|
kaboom();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cyclomatic_complexity = "0"]
|
#[clippy::cyclomatic_complexity = "0"]
|
||||||
fn kaboom() {
|
fn kaboom() {
|
||||||
if 42 == 43 {
|
if 42 == 43 {
|
||||||
panic!();
|
panic!();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![feature(custom_attribute)]
|
|
||||||
#![warn(excessive_precision)]
|
#![warn(excessive_precision)]
|
||||||
#![allow(print_literal)]
|
#![allow(print_literal)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![feature(custom_attribute)]
|
|
||||||
|
|
||||||
|
|
||||||
use std::collections::*;
|
use std::collections::*;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#![feature(custom_attribute, stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes, tool_attributes)]
|
||||||
|
|
||||||
#![allow(unused_parens)]
|
#![allow(unused_parens)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x: i32 = 42;
|
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_1111 == 0; // suggest trailing_zeros
|
||||||
let _ = x & 0b1_1010 == 0; // do not lint
|
let _ = x & 0b1_1010 == 0; // do not lint
|
||||||
let _ = x & 1 == 0; // do not lint
|
let _ = x & 1 == 0; // do not lint
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
error: bit mask could be simplified with a call to `trailing_zeros`
|
error: bit mask could be simplified with a call to `trailing_zeros`
|
||||||
--> $DIR/trailing_zeros.rs:7:31
|
--> $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`
|
| ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 4`
|
||||||
|
|
|
|
||||||
= note: `-D verbose-bit-mask` implied by `-D warnings`
|
= note: `-D verbose-bit-mask` implied by `-D warnings`
|
||||||
|
|||||||
Reference in New Issue
Block a user