Make compatible with unused_variables lint

This commit is contained in:
Devon Hollowood 2015-12-18 16:04:33 -08:00
parent c8d78a70b3
commit 98d21f9fc5
3 changed files with 40 additions and 26 deletions

View file

@ -10,7 +10,8 @@ use rustc::middle::const_eval::ConstVal::Float;
use rustc::middle::const_eval::eval_const_expr_partial;
use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
use utils::{get_item_name, match_path, snippet, span_lint, walk_ptrs_ty, is_integer_literal};
use utils::{get_item_name, match_path, snippet, get_parent_expr, span_lint, walk_ptrs_ty,
is_integer_literal};
use utils::span_help_and_lint;
/// **What it does:** This lint checks for function arguments and let bindings denoted as `ref`. It is `Warn` by default.
@ -323,16 +324,7 @@ impl LateLintPass for PatternPass {
/// **Why is this bad?** A single leading underscore is usually used to indicate that a binding
/// will not be used. Using such a binding breaks this expectation.
///
/// **Known problems:** This lint's idea of a "used" variable is not quite the same as in the
/// built-in `unused_variables` lint. For example, in the following code
/// ```
/// fn foo(y: u32) -> u32) {
/// let _x = 1;
/// _x +=1;
/// y
/// }
/// ```
/// _x will trigger both the `unused_variables` lint and the `used_underscore_binding` lint.
/// **Known problems:** None
///
/// **Example**:
/// ```
@ -362,6 +354,7 @@ impl LateLintPass for UsedUnderscoreBinding {
ident.name.as_str().chars().next() == Some('_') //starts with '_'
&& ident.name.as_str().chars().skip(1).next() != Some('_') //doesn't start with "__"
&& ident.name != ident.unhygienic_name //not in macro
&& is_used(cx, expr)
},
ExprField(_, spanned) => {
let name = spanned.node.as_str();
@ -372,8 +365,21 @@ impl LateLintPass for UsedUnderscoreBinding {
};
if needs_lint {
cx.span_lint(USED_UNDERSCORE_BINDING, expr.span,
"used binding which is prefixed with an underscore. A leading underscore\
"used binding which is prefixed with an underscore. A leading underscore \
signals that a binding will not be used.");
}
}
}
fn is_used(cx: &LateContext, expr: &Expr) -> bool {
if let Some(ref parent) = get_parent_expr(cx, expr) {
match parent.node {
ExprAssign(_, ref rhs) => **rhs == *expr,
ExprAssignOp(_, _, ref rhs) => **rhs == *expr,
_ => is_used(cx, &parent)
}
}
else {
true
}
}

View file

@ -16,8 +16,7 @@ impl Unrelated {
#[deny(needless_range_loop, explicit_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop)]
#[deny(unused_collect)]
#[allow(linkedlist,shadow_unrelated,unnecessary_mut_passed, cyclomatic_complexity,
used_underscore_binding)]
#[allow(linkedlist,shadow_unrelated,unnecessary_mut_passed, cyclomatic_complexity)]
fn main() {
let mut vec = vec![1, 2, 3, 4];
let vec2 = vec![1, 2, 3, 4];
@ -180,8 +179,8 @@ fn main() {
if false { _index = 0 };
for _v in &vec { _index += 1 }
let mut _index = 0;
{ let mut _x = &mut _index; }
let mut index = 0;
{ let mut _x = &mut index; }
for _v in &vec { _index += 1 }
let mut index = 0;

View file

@ -3,13 +3,13 @@
#![deny(clippy)]
/// Test that we lint if we use a binding with a single leading underscore
fn prefix_underscore(_x: u32) -> u32 {
_x + 1 //~ ERROR used binding which is prefixed with an underscore
fn prefix_underscore(_foo: u32) -> u32 {
_foo + 1 //~ ERROR used binding which is prefixed with an underscore
}
/// Test that we lint even if the use is within a macro expansion
fn in_macro(_x: u32) {
println!("{}", _x); //~ ERROR used binding which is prefixed with an underscore
fn in_macro(_foo: u32) {
println!("{}", _foo); //~ ERROR used binding which is prefixed with an underscore
}
/// Test that we do not lint if the underscore is not a prefix
@ -17,14 +17,23 @@ fn non_prefix_underscore(some_foo: u32) -> u32 {
some_foo + 1
}
/// Test that we do not lint if we do not use the binding
fn unused_underscore(_foo: u32) -> u32 {
/// Test that we do not lint if we do not use the binding (simple case)
fn unused_underscore_simple(_foo: u32) -> u32 {
1
}
#[deny(unused_variables)]
/// Test that we do not lint if we do not use the binding (complex case). This checks for
/// compatibility with the built-in `unused_variables` lint.
fn unused_underscore_complex(mut _foo: u32) -> u32 {
_foo += 1;
_foo = 2;
1
}
///Test that we do not lint for multiple underscores
fn multiple_underscores(__x: u32) -> u32 {
__x + 1
fn multiple_underscores(__foo: u32) -> u32 {
__foo + 1
}
// Non-variable bindings with preceding underscore
@ -54,8 +63,8 @@ fn main() {
in_macro(foo);
// possible false positives
let _ = non_prefix_underscore(foo);
let _ = unused_underscore(foo);
let _ = unused_underscore_simple(foo);
let _ = unused_underscore_complex(foo);
let _ = multiple_underscores(foo);
non_variables();
}