@@ -43,7 +43,7 @@ use syntax::abi;
43
43
use syntax:: ast_map;
44
44
use syntax:: attr:: AttrMetaMethods ;
45
45
use syntax:: attr;
46
- use syntax:: codemap:: { Span , NO_EXPANSION } ;
46
+ use syntax:: codemap:: Span ;
47
47
use syntax:: parse:: token;
48
48
use syntax:: { ast, ast_util, visit} ;
49
49
use syntax:: ptr:: P ;
@@ -1473,27 +1473,33 @@ impl LintPass for Stability {
1473
1473
}
1474
1474
1475
1475
fn check_expr ( & mut self , cx : & Context , e : & ast:: Expr ) {
1476
- // skip if `e` is not from macro arguments
1477
- let skip = cx. tcx . sess . codemap ( ) . with_expn_info ( e. span . expn_id , |expninfo| {
1476
+ // first, check if the given expression was generated by a macro or not
1477
+ // we need to go back the expn_info tree to check only the arguments
1478
+ // of the initial macro call, not the nested ones.
1479
+ let mut expnid = e. span . expn_id ;
1480
+ let mut is_internal = false ;
1481
+ while cx. tcx . sess . codemap ( ) . with_expn_info ( expnid, |expninfo| {
1478
1482
match expninfo {
1479
1483
Some ( ref info) => {
1480
- if info. call_site . expn_id != NO_EXPANSION ||
1481
- !( e. span . lo > info. call_site . lo && e. span . hi < info. call_site . hi ) {
1482
- // This code is not from the arguments,
1483
- // or this macro call was generated by an other macro
1484
- // We can't handle it.
1485
- true
1486
- } else if info. callee . span . is_none ( ) {
1487
- // We don't want to mess with compiler builtins.
1488
- true
1484
+ // save the parent expn_id for next loop iteration
1485
+ expnid = info. call_site . expn_id ;
1486
+ if info. callee . span . is_none ( ) {
1487
+ // it's a compiler built-in, we *really* don't want to mess with it
1488
+ // so we skip it, unless it was called by a regular macro, in which case
1489
+ // we will handle the caller macro next turn
1490
+ is_internal = true ;
1491
+ true // continue looping
1489
1492
} else {
1490
- false
1493
+ // was this expression from the current macro arguments ?
1494
+ is_internal = !( e. span . lo > info. call_site . lo &&
1495
+ e. span . hi < info. call_site . hi ) ;
1496
+ true // continue looping
1491
1497
}
1492
1498
} ,
1493
- _ => { false }
1499
+ _ => false // stop looping
1494
1500
}
1495
- } ) ;
1496
- if skip { return ; }
1501
+ } ) { /* empty while loop body */ }
1502
+ if is_internal { return ; }
1497
1503
1498
1504
let mut span = e. span ;
1499
1505
0 commit comments