From fcf70230eb4d0ce6840c6455eb8af95a9650f8b2 Mon Sep 17 00:00:00 2001 From: Ivan Petkov Date: Mon, 23 Feb 2015 22:27:27 -0800 Subject: [PATCH] Properly reimplement `unsafe-code` lint to honor changing lint attributes --- src/librustc/lint/builtin.rs | 54 +++++++++-------------- src/test/compile-fail/lint-unsafe-code.rs | 49 ++++++++++++++++++++ 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 3c06bae177cef..36c812f440fda 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) { - 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 7b17d8877572f..8440cf3a88e10 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