mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-24 06:24:35 +00:00
Rollup merge of #22542 - ipetkov:unsafe-lint, r=huonw
This allows warning or forbidding all uses of unsafe code, whereas previously only unsafe blocks were caught by the lint. The lint has been renamed from `unsafe-blocks` to `unsafe-code` to reflect its new purpose. This is a minor [breaking-change] Closes #22430
This commit is contained in:
commit
98ec45ee0b
@ -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! {
|
||||
|
@ -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,
|
||||
|
@ -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!()
|
||||
}
|
50
src/test/compile-fail/lint-unsafe-code.rs
Normal file
50
src/test/compile-fail/lint-unsafe-code.rs
Normal file
@ -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!()
|
||||
}
|
Loading…
Reference in New Issue
Block a user