Skip to content

Commit fcf7023

Browse files
committed
Properly reimplement unsafe-code lint to honor changing lint attributes
1 parent f0f7ca2 commit fcf7023

File tree

2 files changed

+71
-32
lines changed

2 files changed

+71
-32
lines changed

src/librustc/lint/builtin.rs

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,46 +1292,36 @@ impl LintPass for UnsafeCode {
12921292
}
12931293

12941294
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
1295-
use syntax::ast::Unsafety::Unsafe;
1296-
1297-
fn check_method(cx: &Context, meth: &P<ast::Method>) {
1298-
if let ast::Method_::MethDecl(_, _, _, _, Unsafe, _, _, _) = meth.node {
1299-
cx.span_lint(UNSAFE_CODE, meth.span, "implementation of an `unsafe` method");
1300-
}
1301-
}
1302-
13031295
match it.node {
1304-
ast::ItemFn(_, Unsafe, _, _, _) =>
1305-
cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` function"),
1296+
ast::ItemTrait(ast::Unsafety::Unsafe, _, _, _) =>
1297+
cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait"),
13061298

1307-
ast::ItemTrait(trait_safety, _, _, ref items) => {
1308-
if trait_safety == Unsafe {
1309-
cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait");
1310-
}
1299+
ast::ItemImpl(ast::Unsafety::Unsafe, _, _, _, _, _) =>
1300+
cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait"),
13111301

1312-
for it in items {
1313-
match *it {
1314-
ast::RequiredMethod(ast::TypeMethod { unsafety: Unsafe, span, ..}) =>
1315-
cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method"),
1316-
ast::ProvidedMethod(ref meth) => check_method(cx, meth),
1317-
_ => (),
1318-
}
1319-
}
1320-
},
1302+
_ => return,
1303+
}
1304+
}
13211305

1322-
ast::ItemImpl(impl_safety, _, _, _, _, ref impls) => {
1323-
if impl_safety == Unsafe {
1324-
cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait");
1325-
}
1306+
fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
1307+
_: &ast::Block, span: Span, _: ast::NodeId) {
1308+
match fk {
1309+
visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) =>
1310+
cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
13261311

1327-
for item in impls {
1328-
if let ast::ImplItem::MethodImplItem(ref meth) = *item {
1329-
check_method(cx, meth);
1330-
}
1312+
visit::FkMethod(_, _, m) => {
1313+
if let ast::Method_::MethDecl(_, _, _, _, ast::Unsafety::Unsafe, _, _, _) = m.node {
1314+
cx.span_lint(UNSAFE_CODE, m.span, "implementation of an `unsafe` method")
13311315
}
13321316
},
13331317

1334-
_ => return,
1318+
_ => (),
1319+
}
1320+
}
1321+
1322+
fn check_ty_method(&mut self, cx: &Context, ty_method: &ast::TypeMethod) {
1323+
if let ast::TypeMethod { unsafety: ast::Unsafety::Unsafe, span, ..} = *ty_method {
1324+
cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method")
13351325
}
13361326
}
13371327
}

src/test/compile-fail/lint-unsafe-code.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use std::marker::PhantomFn;
1616

1717
struct Bar;
18+
struct Bar2;
19+
struct Bar3;
1820

1921
#[allow(unsafe_code)]
2022
mod allowed_unsafe {
@@ -46,6 +48,53 @@ impl Baz for Bar {
4648
unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
4749
}
4850

51+
52+
#[allow(unsafe_code)]
53+
trait A {
54+
unsafe fn allowed_unsafe(&self);
55+
unsafe fn allowed_unsafe_provided(&self) {}
56+
}
57+
58+
#[allow(unsafe_code)]
59+
impl Baz for Bar2 {
60+
unsafe fn baz(&self) {}
61+
unsafe fn provided_override(&self) {}
62+
}
63+
64+
impl Baz for Bar3 {
65+
#[allow(unsafe_code)]
66+
unsafe fn baz(&self) {}
67+
unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
68+
}
69+
70+
#[allow(unsafe_code)]
71+
unsafe trait B {
72+
fn dummy(&self) {}
73+
}
74+
75+
trait C {
76+
#[allow(unsafe_code)]
77+
unsafe fn baz(&self);
78+
unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
79+
}
80+
81+
impl C for Bar {
82+
#[allow(unsafe_code)]
83+
unsafe fn baz(&self) {}
84+
unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
85+
}
86+
87+
impl C for Bar2 {
88+
unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method
89+
}
90+
91+
trait D {
92+
#[allow(unsafe_code)]
93+
unsafe fn unsafe_provided(&self) {}
94+
}
95+
96+
impl D for Bar {}
97+
4998
fn main() {
5099
unsafe {} //~ ERROR: usage of an `unsafe` block
51100

0 commit comments

Comments
 (0)