@@ -10,8 +10,8 @@ use rustc_const_math::ConstFloat;
10
10
use syntax:: codemap:: { Span , Spanned , ExpnFormat } ;
11
11
use syntax:: ptr:: P ;
12
12
use utils:: {
13
- get_item_name, get_parent_expr, implements_trait, is_integer_literal , match_path , snippet ,
14
- span_lint, span_lint_and_then, walk_ptrs_ty
13
+ get_item_name, get_parent_expr, implements_trait, in_macro , is_integer_literal , match_path ,
14
+ snippet , span_lint, span_lint_and_then, walk_ptrs_ty
15
15
} ;
16
16
17
17
/// **What it does:** This lint checks for function arguments and let bindings denoted as `ref`.
@@ -405,15 +405,18 @@ impl LateLintPass for UsedUnderscoreBinding {
405
405
}
406
406
let binding = match expr. node {
407
407
ExprPath ( _, ref path) => {
408
- let segment = path. segments
408
+ let binding = path. segments
409
409
. last ( )
410
410
. expect ( "path should always have at least one segment" )
411
- . name ;
412
- if segment. as_str ( ) . starts_with ( '_' ) &&
413
- !segment. as_str ( ) . starts_with ( "__" ) &&
414
- segment != segment. unhygienize ( ) && // not in bang macro
415
- is_used ( cx, expr) {
416
- Some ( segment. as_str ( ) )
411
+ . name
412
+ . as_str ( ) ;
413
+ if binding. starts_with ( '_' ) &&
414
+ !binding. starts_with ( "__" ) &&
415
+ binding != "_result" && // FIXME: #944
416
+ is_used ( cx, expr) &&
417
+ // don't lint if the declaration is in a macro
418
+ non_macro_local ( cx, & cx. tcx . expect_def ( expr. id ) ) {
419
+ Some ( binding)
417
420
} else {
418
421
None
419
422
}
@@ -429,13 +432,11 @@ impl LateLintPass for UsedUnderscoreBinding {
429
432
_ => None ,
430
433
} ;
431
434
if let Some ( binding) = binding {
432
- if binding != "_result" { // FIXME: #944
433
- span_lint ( cx,
434
- USED_UNDERSCORE_BINDING ,
435
- expr. span ,
436
- & format ! ( "used binding `{}` which is prefixed with an underscore. A leading \
437
- underscore signals that a binding will not be used.", binding) ) ;
438
- }
435
+ span_lint ( cx,
436
+ USED_UNDERSCORE_BINDING ,
437
+ expr. span ,
438
+ & format ! ( "used binding `{}` which is prefixed with an underscore. A leading \
439
+ underscore signals that a binding will not be used.", binding) ) ;
439
440
}
440
441
}
441
442
}
@@ -463,3 +464,17 @@ fn in_attributes_expansion(cx: &LateContext, expr: &Expr) -> bool {
463
464
} )
464
465
} )
465
466
}
467
+
468
+ /// Test whether `def` is a variable defined outside a macro.
469
+ fn non_macro_local ( cx : & LateContext , def : & def:: Def ) -> bool {
470
+ match * def {
471
+ def:: Def :: Local ( _, id) | def:: Def :: Upvar ( _, id, _, _) => {
472
+ if let Some ( span) = cx. tcx . map . opt_span ( id) {
473
+ !in_macro ( cx, span)
474
+ } else {
475
+ true
476
+ }
477
+ }
478
+ _ => false ,
479
+ }
480
+ }
0 commit comments