Skip to content

Commit e8cfae4

Browse files
authored
Rollup merge of #57467 - JohnTitor:implement-the-check-attribute-1, r=oli-obk
Implement `check_attribute` to forbid `#[allow_internal_unsafe]` Fixes #56768. r? @oli-obk
2 parents 77727fe + bd1551e commit e8cfae4

File tree

5 files changed

+58
-21
lines changed

5 files changed

+58
-21
lines changed

src/librustc_lint/builtin.rs

+25-18
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ use syntax_pos::{BytePos, Span, SyntaxContext};
4040
use syntax::symbol::keywords;
4141
use syntax::errors::{Applicability, DiagnosticBuilder};
4242
use syntax::print::pprust::expr_to_string;
43+
use syntax::visit::FnKind;
4344

4445
use rustc::hir::{self, GenericParamKind, PatKind};
45-
use rustc::hir::intravisit::FnKind;
4646

4747
use nonstandard_style::{MethodLateContext, method_context};
4848

@@ -216,7 +216,7 @@ impl LintPass for UnsafeCode {
216216
}
217217

218218
impl UnsafeCode {
219-
fn report_unsafe(&self, cx: &LateContext, span: Span, desc: &'static str) {
219+
fn report_unsafe(&self, cx: &EarlyContext, span: Span, desc: &'static str) {
220220
// This comes from a macro that has #[allow_internal_unsafe].
221221
if span.allows_unsafe() {
222222
return;
@@ -226,23 +226,31 @@ impl UnsafeCode {
226226
}
227227
}
228228

229-
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
230-
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
231-
if let hir::ExprKind::Block(ref blk, _) = e.node {
229+
impl EarlyLintPass for UnsafeCode {
230+
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
231+
if attr.check_name("allow_internal_unsafe") {
232+
self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
233+
macros using unsafe without triggering \
234+
the `unsafe_code` lint at their call site");
235+
}
236+
}
237+
238+
fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
239+
if let ast::ExprKind::Block(ref blk, _) = e.node {
232240
// Don't warn about generated blocks, that'll just pollute the output.
233-
if blk.rules == hir::UnsafeBlock(hir::UserProvided) {
241+
if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
234242
self.report_unsafe(cx, blk.span, "usage of an `unsafe` block");
235243
}
236244
}
237245
}
238246

239-
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
247+
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
240248
match it.node {
241-
hir::ItemKind::Trait(_, hir::Unsafety::Unsafe, ..) => {
249+
ast::ItemKind::Trait(_, ast::Unsafety::Unsafe, ..) => {
242250
self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
243251
}
244252

245-
hir::ItemKind::Impl(hir::Unsafety::Unsafe, ..) => {
253+
ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => {
246254
self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait")
247255
}
248256

@@ -251,19 +259,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
251259
}
252260

253261
fn check_fn(&mut self,
254-
cx: &LateContext,
255-
fk: FnKind<'tcx>,
256-
_: &hir::FnDecl,
257-
_: &hir::Body,
262+
cx: &EarlyContext,
263+
fk: FnKind,
264+
_: &ast::FnDecl,
258265
span: Span,
259266
_: ast::NodeId) {
260267
match fk {
261-
FnKind::ItemFn(_, _, hir::FnHeader { unsafety: hir::Unsafety::Unsafe, .. }, ..) => {
268+
FnKind::ItemFn(_, ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, ..) => {
262269
self.report_unsafe(cx, span, "declaration of an `unsafe` function")
263270
}
264271

265272
FnKind::Method(_, sig, ..) => {
266-
if sig.header.unsafety == hir::Unsafety::Unsafe {
273+
if sig.header.unsafety == ast::Unsafety::Unsafe {
267274
self.report_unsafe(cx, span, "implementation of an `unsafe` method")
268275
}
269276
}
@@ -272,9 +279,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
272279
}
273280
}
274281

275-
fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
276-
if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) = item.node {
277-
if sig.header.unsafety == hir::Unsafety::Unsafe {
282+
fn check_trait_item(&mut self, cx: &EarlyContext, item: &ast::TraitItem) {
283+
if let ast::TraitItemKind::Method(ref sig, None) = item.node {
284+
if sig.header.unsafety == ast::Unsafety::Unsafe {
278285
self.report_unsafe(cx, item.span, "declaration of an `unsafe` method")
279286
}
280287
}

src/librustc_lint/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
111111
add_early_builtin!(sess,
112112
UnusedParens,
113113
UnusedImportBraces,
114+
UnsafeCode,
114115
AnonymousParameters,
115116
UnusedDocComment,
116117
BadRepr,
@@ -134,7 +135,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
134135
NonSnakeCase: NonSnakeCase,
135136
NonUpperCaseGlobals: NonUpperCaseGlobals,
136137
NonShorthandFieldPatterns: NonShorthandFieldPatterns,
137-
UnsafeCode: UnsafeCode,
138138
UnusedAllocation: UnusedAllocation,
139139
MissingCopyImplementations: MissingCopyImplementations,
140140
UnstableFeatures: UnstableFeatures,

src/libsyntax/ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -853,13 +853,13 @@ pub struct Field {
853853

854854
pub type SpannedIdent = Spanned<Ident>;
855855

856-
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
856+
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
857857
pub enum BlockCheckMode {
858858
Default,
859859
Unsafe(UnsafeSource),
860860
}
861861

862-
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
862+
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
863863
pub enum UnsafeSource {
864864
CompilerGenerated,
865865
UserProvided,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![forbid(unsafe_code)]
2+
#![feature(allow_internal_unsafe)]
3+
4+
#[allow_internal_unsafe]
5+
//~^ ERROR: `allow_internal_unsafe` allows defining
6+
macro_rules! evil {
7+
($e:expr) => {
8+
unsafe {
9+
$e
10+
}
11+
}
12+
}
13+
14+
fn main() {
15+
println!("{}", evil!(*(0 as *const u8)));
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: `allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
2+
--> $DIR/lint-forbid-internal-unsafe.rs:4:1
3+
|
4+
LL | #[allow_internal_unsafe]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: lint level defined here
8+
--> $DIR/lint-forbid-internal-unsafe.rs:1:11
9+
|
10+
LL | #![forbid(unsafe_code)]
11+
| ^^^^^^^^^^^
12+
13+
error: aborting due to previous error
14+

0 commit comments

Comments
 (0)