about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVictor Berger <victor.berger@m4x.org>2014-09-18 00:15:36 +0200
committerVictor Berger <victor.berger@m4x.org>2014-09-22 19:28:07 +0200
commiteb58ac126e638287998959a20aa91ffa730b95c2 (patch)
tree498addaa91b117fe62b203a6d3e4f1cf04b3734a
parent3907a13f697feb007ab4824ee26f998d56a1311f (diff)
downloadrust-eb58ac126e638287998959a20aa91ffa730b95c2.tar.gz
rust-eb58ac126e638287998959a20aa91ffa730b95c2.zip
Lint stability now checks macro arguments.
Closes #17185.
-rw-r--r--src/librustc/lint/builtin.rs23
-rw-r--r--src/test/auxiliary/lint_stability.rs10
-rw-r--r--src/test/compile-fail/lint-stability.rs8
3 files changed, 36 insertions, 5 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 588e275455a..6c3f96bbec6 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -1490,8 +1490,27 @@ impl LintPass for Stability {
     }
 
     fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        // if the expression was produced by a macro expansion,
-        if e.span.expn_id != NO_EXPANSION { return }
+        // skip if `e` is not from macro arguments
+        let skip = cx.tcx.sess.codemap().with_expn_info(e.span.expn_id, |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
+                    } else {
+                        false
+                    }
+                },
+                _ => { false }
+            }
+        });
+        if skip { return; }
 
         let id = match e.node {
             ast::ExprPath(..) | ast::ExprStruct(..) => {
diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs
index b0090c63969..bae86f04b23 100644
--- a/src/test/auxiliary/lint_stability.rs
+++ b/src/test/auxiliary/lint_stability.rs
@@ -181,3 +181,13 @@ pub struct LockedTupleStruct(pub int);
 macro_rules! macro_test(
     () => (deprecated());
 )
+
+#[macro_export]
+macro_rules! macro_test_arg(
+    ($func:expr) => ($func);
+)
+
+#[macro_export]
+macro_rules! macro_test_arg_nested(
+    ($func:ident) => (macro_test_arg!($func()));
+)
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index f5cee22ac2c..6a36e270740 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -109,12 +109,14 @@ mod cross_crate {
         let _ = FrozenTupleStruct (1);
         let _ = LockedTupleStruct (1);
 
-        // At the moment, the following just checks that the stability
-        // level of expanded code does not trigger the
-        // lint. Eventually, we will want to lint the contents of the
+        // At the moment, the lint checker only checks stability in
+        // in the arguments of macros.
+        // Eventually, we will want to lint the contents of the
         // macro in the module *defining* it. Also, stability levels
         // on macros themselves are not yet linted.
         macro_test!();
+        macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item: text
+        macro_test_arg_nested!(deprecated_text);
     }
 
     fn test_method_param<F: Trait>(foo: F) {