about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-06 14:06:59 +0000
committerbors <bors@rust-lang.org>2014-11-06 14:06:59 +0000
commit60a669a1743b845dfa349684ef057bc98ec6d840 (patch)
tree2861d1de805d6599fef11e326e0db320ead9734b
parente84e7a00ddec76570bbaa9afea385d544f616814 (diff)
parent68ac44cb97d9f7fd5e552aabb516f61cbb5b6760 (diff)
auto merge of #18608 : alexcrichton/rust/lint-some-crates, r=aturon
This commit adds support for linting `extern crate` statements for stability
attributes attached to the crate itself. This is likely to be the mechanism used
to deny access to experimental crates that are part of the standard
distribution.

cc #18585 

r? @aturon
-rw-r--r--src/librustc/lint/builtin.rs75
-rw-r--r--src/test/compile-fail/lint-output-format.rs2
-rw-r--r--src/test/compile-fail/lint-stability.rs4
3 files changed, 51 insertions, 30 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index f72b1262bdf..b60b2ba984e 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -45,7 +45,7 @@ use syntax::ast_map;
 use syntax::ast_util::is_shift_binop;
 use syntax::attr::AttrMetaMethods;
 use syntax::attr;
-use syntax::codemap::Span;
+use syntax::codemap::{Span, DUMMY_SP};
 use syntax::parse::token;
 use syntax::{ast, ast_util, visit};
 use syntax::ast::{TyI, TyU, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
@@ -1553,11 +1553,57 @@ declare_lint!(UNSTABLE, Allow,
 /// `#[unstable]` attributes, or no stability attribute.
 pub struct Stability;
 
+impl Stability {
+    fn lint(&self, cx: &Context, id: ast::DefId, span: Span) {
+        let stability = stability::lookup(cx.tcx, id);
+        let cross_crate = !ast_util::is_local(id);
+
+        // stability attributes are promises made across crates; only
+        // check DEPRECATED for crate-local usage.
+        let (lint, label) = match stability {
+            // no stability attributes == Unstable
+            None if cross_crate => (UNSTABLE, "unmarked"),
+            Some(attr::Stability { level: attr::Unstable, .. }) if cross_crate =>
+                (UNSTABLE, "unstable"),
+            Some(attr::Stability { level: attr::Experimental, .. }) if cross_crate =>
+                (EXPERIMENTAL, "experimental"),
+            Some(attr::Stability { level: attr::Deprecated, .. }) =>
+                (DEPRECATED, "deprecated"),
+            _ => return
+        };
+
+        let msg = match stability {
+            Some(attr::Stability { text: Some(ref s), .. }) => {
+                format!("use of {} item: {}", label, *s)
+            }
+            _ => format!("use of {} item", label)
+        };
+
+        cx.span_lint(lint, span, msg.as_slice());
+    }
+}
+
 impl LintPass for Stability {
     fn get_lints(&self) -> LintArray {
         lint_array!(DEPRECATED, EXPERIMENTAL, UNSTABLE)
     }
 
+    fn check_view_item(&mut self, cx: &Context, item: &ast::ViewItem) {
+        // compiler-generated `extern crate` statements have a dummy span.
+        if item.span == DUMMY_SP { return }
+
+        let id = match item.node {
+            ast::ViewItemExternCrate(_, _, id) => id,
+            ast::ViewItemUse(..) => return,
+        };
+        let cnum = match cx.tcx.sess.cstore.find_extern_mod_stmt_cnum(id) {
+            Some(cnum) => cnum,
+            None => return,
+        };
+        let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID };
+        self.lint(cx, id, item.span);
+    }
+
     fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
         // 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
@@ -1629,32 +1675,7 @@ impl LintPass for Stability {
             }
             _ => return
         };
-
-        let stability = stability::lookup(cx.tcx, id);
-        let cross_crate = !ast_util::is_local(id);
-
-        // stability attributes are promises made across crates; only
-        // check DEPRECATED for crate-local usage.
-        let (lint, label) = match stability {
-            // no stability attributes == Unstable
-            None if cross_crate => (UNSTABLE, "unmarked"),
-            Some(attr::Stability { level: attr::Unstable, .. }) if cross_crate =>
-                (UNSTABLE, "unstable"),
-            Some(attr::Stability { level: attr::Experimental, .. }) if cross_crate =>
-                (EXPERIMENTAL, "experimental"),
-            Some(attr::Stability { level: attr::Deprecated, .. }) =>
-                (DEPRECATED, "deprecated"),
-            _ => return
-        };
-
-        let msg = match stability {
-            Some(attr::Stability { text: Some(ref s), .. }) => {
-                format!("use of {} item: {}", label, *s)
-            }
-            _ => format!("use of {} item", label)
-        };
-
-        cx.span_lint(lint, span, msg.as_slice());
+        self.lint(cx, id, span);
     }
 }
 
diff --git a/src/test/compile-fail/lint-output-format.rs b/src/test/compile-fail/lint-output-format.rs
index db60002b468..35721ee5b14 100644
--- a/src/test/compile-fail/lint-output-format.rs
+++ b/src/test/compile-fail/lint-output-format.rs
@@ -11,7 +11,7 @@
 // compile-flags:-F experimental -D unstable
 // aux-build:lint_output_format.rs
 
-extern crate lint_output_format;
+extern crate lint_output_format; //~ ERROR: use of unmarked item
 use lint_output_format::{foo, bar, baz};
 
 fn main() {
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index fdb0d801164..babf12e97f2 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -19,7 +19,7 @@
 
 mod cross_crate {
     #[phase(plugin, link)]
-    extern crate lint_stability;
+    extern crate lint_stability; //~ ERROR: use of unmarked item
     use self::lint_stability::*;
 
     fn test() {
@@ -144,7 +144,7 @@ mod cross_crate {
 }
 
 mod inheritance {
-    extern crate inherited_stability;
+    extern crate inherited_stability; //~ ERROR: use of experimental item
     use self::inherited_stability::*;
 
     fn test_inheritance() {