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) { + 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 or the MIT license -// , 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 or the MIT license +// , 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!() +}