]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Add some more checks to the stability lint
authorBrian Anderson <banderson@mozilla.com>
Wed, 5 Nov 2014 23:49:37 +0000 (15:49 -0800)
committerBrian Anderson <banderson@mozilla.com>
Thu, 6 Nov 2014 01:35:40 +0000 (17:35 -0800)
This catches uses of unstable traits in

```
trait Foo: UnstableTrait { }
```

and

```
impl UnstableTrait for Foo { }
```

src/librustc/lint/builtin.rs
src/test/auxiliary/lint_stability.rs
src/test/compile-fail/lint-stability.rs

index f084c8caea5437d599606f1a5cabf1cd90663408..ec522d7078498dc4b9847b60ef2cc662169ad671 100644 (file)
@@ -1581,34 +1581,12 @@ fn lint(&self, cx: &Context, id: ast::DefId, span: Span) {
 
         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) {
+    fn is_internal(&self, cx: &Context, span: Span) -> bool {
         // 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 expnid = span.expn_id;
         let mut is_internal = false;
         while cx.tcx.sess.codemap().with_expn_info(expnid, |expninfo| {
             match expninfo {
@@ -1623,15 +1601,41 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                         true // continue looping
                     } else {
                         // was this expression from the current macro arguments ?
-                        is_internal = !( e.span.lo > info.call_site.lo &&
-                                         e.span.hi < info.call_site.hi );
+                        is_internal = !( span.lo > info.call_site.lo &&
+                                         span.hi < info.call_site.hi );
                         true // continue looping
                     }
                 },
                 _ => false // stop looping
             }
         }) { /* empty while loop body */ }
-        if is_internal { return; }
+        return is_internal;
+    }
+}
+
+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) {
+        if self.is_internal(cx, e.span) { return; }
 
         let mut span = e.span;
 
@@ -1677,6 +1681,29 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
         };
         self.lint(cx, id, span);
     }
+
+    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
+        if self.is_internal(cx, item.span) { return }
+
+        match item.node {
+            ast::ItemTrait(_, _, ref supertraits, _) => {
+                for t in supertraits.iter() {
+                    match *t {
+                        ast::TraitTyParamBound(ref t) => {
+                            let id = ty::trait_ref_to_def_id(cx.tcx, t);
+                            self.lint(cx, id, t.path.span);
+                        }
+                        _ => (/* pass */)
+                    }
+                }
+            }
+            ast::ItemImpl(_, Some(ref t), _, _) => {
+                let id = ty::trait_ref_to_def_id(cx.tcx, t);
+                self.lint(cx, id, t.path.span);
+            }
+            _ => (/* pass */)
+        }
+    }
 }
 
 declare_lint!(pub UNUSED_IMPORTS, Warn,
index 06031eb6c6ccfee9b141a76604d947f607fd540c..0be2f31e2827fff2e3b777c80977475a9a139851 100644 (file)
@@ -118,6 +118,9 @@ fn trait_frozen_text(&self) {}
 
 impl Trait for MethodTester {}
 
+#[experimental]
+pub trait ExperimentalTrait {}
+
 #[deprecated]
 pub struct DeprecatedStruct { pub i: int }
 #[experimental]
index babf12e97f2a9adf88ea6512546667edb7352dad..2074d007502304706a2e1ecd0cb064afbdd3e2e0 100644 (file)
@@ -141,6 +141,12 @@ fn test_method_object(foo: &Trait) {
         foo.trait_unmarked(); //~ ERROR use of unmarked item
         foo.trait_stable();
     }
+
+    struct S;
+
+    impl ExperimentalTrait for S { } //~ ERROR use of experimental item
+
+    trait LocalTrait : ExperimentalTrait { } //~ ERROR use of experimental item
 }
 
 mod inheritance {
@@ -444,6 +450,15 @@ fn test_method_object(foo: &Trait) {
         foo.trait_unmarked();
         foo.trait_stable();
     }
+
+    #[deprecated]
+    pub trait DeprecatedTrait {}
+
+    struct S;
+
+    impl DeprecatedTrait for S { } //~ ERROR use of deprecated item
+
+    trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item
 }
 
 fn main() {}