about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/lint/builtin.rs58
-rw-r--r--src/librustc/lint/context.rs4
-rw-r--r--src/test/compile-fail/lint-unsafe-block.rs28
-rw-r--r--src/test/compile-fail/lint-unsafe-code.rs50
4 files changed, 103 insertions, 37 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index eb51046d7c9..a7f4a8cc9a3 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -1269,27 +1269,71 @@ impl LintPass for UnusedUnsafe {
 }
 
 declare_lint! {
-    UNSAFE_BLOCKS,
+    UNSAFE_CODE,
     Allow,
-    "usage of an `unsafe` block"
+    "usage of `unsafe` code"
 }
 
 #[derive(Copy)]
-pub struct UnsafeBlocks;
+pub struct UnsafeCode;
 
-impl LintPass for UnsafeBlocks {
+impl LintPass for UnsafeCode {
     fn get_lints(&self) -> LintArray {
-        lint_array!(UNSAFE_BLOCKS)
+        lint_array!(UNSAFE_CODE)
     }
 
     fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
         if let ast::ExprBlock(ref blk) = e.node {
             // Don't warn about generated blocks, that'll just pollute the output.
             if blk.rules == ast::UnsafeBlock(ast::UserProvided) {
-                cx.span_lint(UNSAFE_BLOCKS, blk.span, "usage of an `unsafe` block");
+                cx.span_lint(UNSAFE_CODE, blk.span, "usage of an `unsafe` block");
             }
         }
     }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        use syntax::ast::Unsafety::Unsafe;
+
+        fn check_method(cx: &Context, meth: &P<ast::Method>) {
+            if let ast::Method_::MethDecl(_, _, _, _, Unsafe, _, _, _) = meth.node {
+                cx.span_lint(UNSAFE_CODE, meth.span, "implementation of an `unsafe` method");
+            }
+        }
+
+        match it.node {
+            ast::ItemFn(_, Unsafe, _, _, _) =>
+                cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` function"),
+
+            ast::ItemTrait(trait_safety, _, _, ref items) => {
+                if trait_safety == Unsafe {
+                    cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait");
+                }
+
+                for it in items {
+                    match *it {
+                        ast::RequiredMethod(ast::TypeMethod { unsafety: Unsafe, span, ..}) =>
+                            cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method"),
+                        ast::ProvidedMethod(ref meth) => check_method(cx, meth),
+                        _ => (),
+                    }
+                }
+            },
+
+            ast::ItemImpl(impl_safety, _, _, _, _, ref impls) => {
+                if impl_safety == Unsafe {
+                    cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait");
+                }
+
+                for item in impls {
+                    if let ast::ImplItem::MethodImplItem(ref meth) = *item {
+                        check_method(cx, meth);
+                    }
+                }
+            },
+
+            _ => return,
+        }
+    }
 }
 
 declare_lint! {
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 42a6861f452..b6e746e1b1a 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -206,7 +206,7 @@ impl LintStore {
                      UnusedImportBraces,
                      NonShorthandFieldPatterns,
                      UnusedUnsafe,
-                     UnsafeBlocks,
+                     UnsafeCode,
                      UnusedMut,
                      UnusedAllocation,
                      MissingCopyImplementations,
diff --git a/src/test/compile-fail/lint-unsafe-block.rs b/src/test/compile-fail/lint-unsafe-block.rs
deleted file mode 100644
index 56d2b2cd6c0..00000000000
--- a/src/test/compile-fail/lint-unsafe-block.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(unused_unsafe)]
-#![allow(dead_code)]
-#![deny(unsafe_blocks)]
-unsafe fn allowed() {}
-
-#[allow(unsafe_blocks)] fn also_allowed() { unsafe {} }
-
-macro_rules! unsafe_in_macro {
-    () => {
-        unsafe {} //~ ERROR: usage of an `unsafe` block
-    }
-}
-
-fn main() {
-    unsafe {} //~ ERROR: usage of an `unsafe` block
-
-    unsafe_in_macro!()
-}
diff --git a/src/test/compile-fail/lint-unsafe-code.rs b/src/test/compile-fail/lint-unsafe-code.rs
new file mode 100644
index 00000000000..486e7142f27
--- /dev/null
+++ b/src/test/compile-fail/lint-unsafe-code.rs
@@ -0,0 +1,50 @@
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_unsafe)]
+#![allow(dead_code)]
+#![deny(unsafe_code)]
+
+struct Bar;
+
+#[allow(unsafe_code)]
+mod allowed_unsafe {
+    fn allowed() { unsafe {} }
+    unsafe fn also_allowed() {}
+    unsafe trait AllowedUnsafe {}
+    unsafe impl AllowedUnsafe for super::Bar {}
+}
+
+macro_rules! unsafe_in_macro {
+    () => {
+        unsafe {} //~ ERROR: usage of an `unsafe` block
+    }
+}
+
+unsafe fn baz() {} //~ ERROR: declaration of an `unsafe` function
+unsafe trait Foo {} //~ ERROR: declaration of an `unsafe` trait
+unsafe impl Foo for Bar {} //~ ERROR: implementation of an `unsafe` trait
+
+trait Baz {
+    unsafe fn baz(&self); //~ ERROR: declaration of an `unsafe` method
+    unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
+    unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+impl Baz for Bar {
+    unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method
+    unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+fn main() {
+    unsafe {} //~ ERROR: usage of an `unsafe` block
+
+    unsafe_in_macro!()
+}