Skip to content

Commit dd55c80

Browse files
committed
Stability lint checker now handles nested macros.
Closes #17185.
1 parent 6353465 commit dd55c80

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

src/librustc/lint/builtin.rs

+22-16
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use syntax::abi;
4343
use syntax::ast_map;
4444
use syntax::attr::AttrMetaMethods;
4545
use syntax::attr;
46-
use syntax::codemap::{Span, NO_EXPANSION};
46+
use syntax::codemap::Span;
4747
use syntax::parse::token;
4848
use syntax::{ast, ast_util, visit};
4949
use syntax::ptr::P;
@@ -1473,27 +1473,33 @@ impl LintPass for Stability {
14731473
}
14741474

14751475
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| {
14781482
match expninfo {
14791483
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
14891492
} 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
14911497
}
14921498
},
1493-
_ => { false }
1499+
_ => false // stop looping
14941500
}
1495-
});
1496-
if skip { return; }
1501+
}) { /* empty while loop body */ }
1502+
if is_internal { return; }
14971503

14981504
let mut span = e.span;
14991505

src/test/compile-fail/lint-stability.rs

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ mod cross_crate {
116116
// on macros themselves are not yet linted.
117117
macro_test!();
118118
macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item: text
119+
macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item: text
119120
macro_test_arg_nested!(deprecated_text);
120121
}
121122

0 commit comments

Comments
 (0)