diff options
| author | Victor Berger <victor.berger@m4x.org> | 2014-09-24 11:14:19 +0200 |
|---|---|---|
| committer | Victor Berger <victor.berger@m4x.org> | 2014-10-20 23:48:29 +0200 |
| commit | dd55c8003cb9c4b065e8a8e54bbc0496ac0a3dfd (patch) | |
| tree | 6b2ee9c0c4910fb6ace8d65d5f9c1b8c47667cb7 /src | |
| parent | 6353465f4df5cc4330f85314a76ff00e0a9a59a0 (diff) | |
| download | rust-dd55c8003cb9c4b065e8a8e54bbc0496ac0a3dfd.tar.gz rust-dd55c8003cb9c4b065e8a8e54bbc0496ac0a3dfd.zip | |
Stability lint checker now handles nested macros.
Closes #17185.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/lint/builtin.rs | 38 | ||||
| -rw-r--r-- | src/test/compile-fail/lint-stability.rs | 1 |
2 files changed, 23 insertions, 16 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 2205dc42d47..69575e51e0f 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -43,7 +43,7 @@ use syntax::abi; use syntax::ast_map; use syntax::attr::AttrMetaMethods; use syntax::attr; -use syntax::codemap::{Span, NO_EXPANSION}; +use syntax::codemap::Span; use syntax::parse::token; use syntax::{ast, ast_util, visit}; use syntax::ptr::P; @@ -1473,27 +1473,33 @@ impl LintPass for Stability { } fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { - // skip if `e` is not from macro arguments - let skip = cx.tcx.sess.codemap().with_expn_info(e.span.expn_id, |expninfo| { + // first, check if the given expression was generated by a macro or not + // we need to go back the expn_info tree to check only the arguments + // of the initial macro call, not the nested ones. + let mut expnid = e.span.expn_id; + let mut is_internal = false; + while cx.tcx.sess.codemap().with_expn_info(expnid, |expninfo| { match expninfo { Some(ref info) => { - if info.call_site.expn_id != NO_EXPANSION || - !( e.span.lo > info.call_site.lo && e.span.hi < info.call_site.hi ) { - // This code is not from the arguments, - // or this macro call was generated by an other macro - // We can't handle it. - true - } else if info.callee.span.is_none() { - // We don't want to mess with compiler builtins. - true + // save the parent expn_id for next loop iteration + expnid = info.call_site.expn_id; + if info.callee.span.is_none() { + // it's a compiler built-in, we *really* don't want to mess with it + // so we skip it, unless it was called by a regular macro, in which case + // we will handle the caller macro next turn + is_internal = true; + true // continue looping } else { - false + // was this expression from the current macro arguments ? + is_internal = !( e.span.lo > info.call_site.lo && + e.span.hi < info.call_site.hi ); + true // continue looping } }, - _ => { false } + _ => false // stop looping } - }); - if skip { return; } + }) { /* empty while loop body */ } + if is_internal { return; } let mut span = e.span; diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs index 6a36e270740..fdb0d801164 100644 --- a/src/test/compile-fail/lint-stability.rs +++ b/src/test/compile-fail/lint-stability.rs @@ -116,6 +116,7 @@ mod cross_crate { // on macros themselves are not yet linted. macro_test!(); macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item: text + macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item: text macro_test_arg_nested!(deprecated_text); } |
