about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/lint/builtin.rs54
-rw-r--r--src/test/compile-fail/lint-unsafe-code.rs49
2 files changed, 71 insertions, 32 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 8a00622486d..9b5e94e87a1 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -1292,46 +1292,36 @@ impl LintPass for UnsafeCode {
     }
 
     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(ast::Unsafety::Unsafe, _, _, _) =>
+                cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait"),
 
-            ast::ItemTrait(trait_safety, _, _, ref items) => {
-                if trait_safety == Unsafe {
-                    cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait");
-                }
+            ast::ItemImpl(ast::Unsafety::Unsafe, _, _, _, _, _) =>
+                cx.span_lint(UNSAFE_CODE, it.span, "implementation 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),
-                        _ => (),
-                    }
-                }
-            },
+            _ => return,
+        }
+    }
 
-            ast::ItemImpl(impl_safety, _, _, _, _, ref impls) => {
-                if impl_safety == Unsafe {
-                    cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait");
-                }
+    fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
+                _: &ast::Block, span: Span, _: ast::NodeId) {
+        match fk {
+            visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) =>
+                cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
 
-                for item in impls {
-                    if let ast::ImplItem::MethodImplItem(ref meth) = *item {
-                        check_method(cx, meth);
-                    }
+            visit::FkMethod(_, _, m) => {
+                if let ast::Method_::MethDecl(_, _, _, _, ast::Unsafety::Unsafe, _, _, _) = m.node {
+                    cx.span_lint(UNSAFE_CODE, m.span, "implementation of an `unsafe` method")
                 }
             },
 
-            _ => return,
+            _ => (),
+        }
+    }
+
+    fn check_ty_method(&mut self, cx: &Context, ty_method: &ast::TypeMethod) {
+        if let ast::TypeMethod { unsafety: ast::Unsafety::Unsafe, span, ..} = *ty_method {
+            cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method")
         }
     }
 }
diff --git a/src/test/compile-fail/lint-unsafe-code.rs b/src/test/compile-fail/lint-unsafe-code.rs
index 7b17d887757..8440cf3a88e 100644
--- a/src/test/compile-fail/lint-unsafe-code.rs
+++ b/src/test/compile-fail/lint-unsafe-code.rs
@@ -15,6 +15,8 @@
 use std::marker::PhantomFn;
 
 struct Bar;
+struct Bar2;
+struct Bar3;
 
 #[allow(unsafe_code)]
 mod allowed_unsafe {
@@ -46,6 +48,53 @@ impl Baz for Bar {
     unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
 }
 
+
+#[allow(unsafe_code)]
+trait A {
+    unsafe fn allowed_unsafe(&self);
+    unsafe fn allowed_unsafe_provided(&self) {}
+}
+
+#[allow(unsafe_code)]
+impl Baz for Bar2 {
+    unsafe fn baz(&self) {}
+    unsafe fn provided_override(&self) {}
+}
+
+impl Baz for Bar3 {
+    #[allow(unsafe_code)]
+    unsafe fn baz(&self) {}
+    unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+#[allow(unsafe_code)]
+unsafe trait B {
+    fn dummy(&self) {}
+}
+
+trait C {
+    #[allow(unsafe_code)]
+    unsafe fn baz(&self);
+    unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+impl C for Bar {
+    #[allow(unsafe_code)]
+    unsafe fn baz(&self) {}
+    unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+impl C for Bar2 {
+    unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+trait D {
+    #[allow(unsafe_code)]
+    unsafe fn unsafe_provided(&self) {}
+}
+
+impl D for Bar {}
+
 fn main() {
     unsafe {} //~ ERROR: usage of an `unsafe` block