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
This commit is contained in:
commit
e8cfae4140
@ -40,9 +40,9 @@ use syntax_pos::{BytePos, Span, SyntaxContext};
|
|||||||
use syntax::symbol::keywords;
|
use syntax::symbol::keywords;
|
||||||
use syntax::errors::{Applicability, DiagnosticBuilder};
|
use syntax::errors::{Applicability, DiagnosticBuilder};
|
||||||
use syntax::print::pprust::expr_to_string;
|
use syntax::print::pprust::expr_to_string;
|
||||||
|
use syntax::visit::FnKind;
|
||||||
|
|
||||||
use rustc::hir::{self, GenericParamKind, PatKind};
|
use rustc::hir::{self, GenericParamKind, PatKind};
|
||||||
use rustc::hir::intravisit::FnKind;
|
|
||||||
|
|
||||||
use nonstandard_style::{MethodLateContext, method_context};
|
use nonstandard_style::{MethodLateContext, method_context};
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ impl LintPass for UnsafeCode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UnsafeCode {
|
impl UnsafeCode {
|
||||||
fn report_unsafe(&self, cx: &LateContext, span: Span, desc: &'static str) {
|
fn report_unsafe(&self, cx: &EarlyContext, span: Span, desc: &'static str) {
|
||||||
// This comes from a macro that has #[allow_internal_unsafe].
|
// This comes from a macro that has #[allow_internal_unsafe].
|
||||||
if span.allows_unsafe() {
|
if span.allows_unsafe() {
|
||||||
return;
|
return;
|
||||||
@ -226,23 +226,31 @@ impl UnsafeCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
|
impl EarlyLintPass for UnsafeCode {
|
||||||
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
|
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
|
||||||
if let hir::ExprKind::Block(ref blk, _) = e.node {
|
if attr.check_name("allow_internal_unsafe") {
|
||||||
|
self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
|
||||||
|
macros using unsafe without triggering \
|
||||||
|
the `unsafe_code` lint at their call site");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
|
||||||
|
if let ast::ExprKind::Block(ref blk, _) = e.node {
|
||||||
// Don't warn about generated blocks, that'll just pollute the output.
|
// Don't warn about generated blocks, that'll just pollute the output.
|
||||||
if blk.rules == hir::UnsafeBlock(hir::UserProvided) {
|
if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
|
||||||
self.report_unsafe(cx, blk.span, "usage of an `unsafe` block");
|
self.report_unsafe(cx, blk.span, "usage of an `unsafe` block");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
|
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
|
||||||
match it.node {
|
match it.node {
|
||||||
hir::ItemKind::Trait(_, hir::Unsafety::Unsafe, ..) => {
|
ast::ItemKind::Trait(_, ast::Unsafety::Unsafe, ..) => {
|
||||||
self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
|
self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ItemKind::Impl(hir::Unsafety::Unsafe, ..) => {
|
ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => {
|
||||||
self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait")
|
self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,19 +259,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_fn(&mut self,
|
fn check_fn(&mut self,
|
||||||
cx: &LateContext,
|
cx: &EarlyContext,
|
||||||
fk: FnKind<'tcx>,
|
fk: FnKind,
|
||||||
_: &hir::FnDecl,
|
_: &ast::FnDecl,
|
||||||
_: &hir::Body,
|
|
||||||
span: Span,
|
span: Span,
|
||||||
_: ast::NodeId) {
|
_: ast::NodeId) {
|
||||||
match fk {
|
match fk {
|
||||||
FnKind::ItemFn(_, _, hir::FnHeader { unsafety: hir::Unsafety::Unsafe, .. }, ..) => {
|
FnKind::ItemFn(_, ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, ..) => {
|
||||||
self.report_unsafe(cx, span, "declaration of an `unsafe` function")
|
self.report_unsafe(cx, span, "declaration of an `unsafe` function")
|
||||||
}
|
}
|
||||||
|
|
||||||
FnKind::Method(_, sig, ..) => {
|
FnKind::Method(_, sig, ..) => {
|
||||||
if sig.header.unsafety == hir::Unsafety::Unsafe {
|
if sig.header.unsafety == ast::Unsafety::Unsafe {
|
||||||
self.report_unsafe(cx, span, "implementation of an `unsafe` method")
|
self.report_unsafe(cx, span, "implementation of an `unsafe` method")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -272,9 +279,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
|
fn check_trait_item(&mut self, cx: &EarlyContext, item: &ast::TraitItem) {
|
||||||
if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) = item.node {
|
if let ast::TraitItemKind::Method(ref sig, None) = item.node {
|
||||||
if sig.header.unsafety == hir::Unsafety::Unsafe {
|
if sig.header.unsafety == ast::Unsafety::Unsafe {
|
||||||
self.report_unsafe(cx, item.span, "declaration of an `unsafe` method")
|
self.report_unsafe(cx, item.span, "declaration of an `unsafe` method")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||||||
add_early_builtin!(sess,
|
add_early_builtin!(sess,
|
||||||
UnusedParens,
|
UnusedParens,
|
||||||
UnusedImportBraces,
|
UnusedImportBraces,
|
||||||
|
UnsafeCode,
|
||||||
AnonymousParameters,
|
AnonymousParameters,
|
||||||
UnusedDocComment,
|
UnusedDocComment,
|
||||||
BadRepr,
|
BadRepr,
|
||||||
@ -134,7 +135,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||||||
NonSnakeCase: NonSnakeCase,
|
NonSnakeCase: NonSnakeCase,
|
||||||
NonUpperCaseGlobals: NonUpperCaseGlobals,
|
NonUpperCaseGlobals: NonUpperCaseGlobals,
|
||||||
NonShorthandFieldPatterns: NonShorthandFieldPatterns,
|
NonShorthandFieldPatterns: NonShorthandFieldPatterns,
|
||||||
UnsafeCode: UnsafeCode,
|
|
||||||
UnusedAllocation: UnusedAllocation,
|
UnusedAllocation: UnusedAllocation,
|
||||||
MissingCopyImplementations: MissingCopyImplementations,
|
MissingCopyImplementations: MissingCopyImplementations,
|
||||||
UnstableFeatures: UnstableFeatures,
|
UnstableFeatures: UnstableFeatures,
|
||||||
|
@ -853,13 +853,13 @@ pub struct Field {
|
|||||||
|
|
||||||
pub type SpannedIdent = Spanned<Ident>;
|
pub type SpannedIdent = Spanned<Ident>;
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
|
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
|
||||||
pub enum BlockCheckMode {
|
pub enum BlockCheckMode {
|
||||||
Default,
|
Default,
|
||||||
Unsafe(UnsafeSource),
|
Unsafe(UnsafeSource),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
|
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
|
||||||
pub enum UnsafeSource {
|
pub enum UnsafeSource {
|
||||||
CompilerGenerated,
|
CompilerGenerated,
|
||||||
UserProvided,
|
UserProvided,
|
||||||
|
16
src/test/ui/lint/lint-forbid-internal-unsafe.rs
Normal file
16
src/test/ui/lint/lint-forbid-internal-unsafe.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#![forbid(unsafe_code)]
|
||||||
|
#![feature(allow_internal_unsafe)]
|
||||||
|
|
||||||
|
#[allow_internal_unsafe]
|
||||||
|
//~^ ERROR: `allow_internal_unsafe` allows defining
|
||||||
|
macro_rules! evil {
|
||||||
|
($e:expr) => {
|
||||||
|
unsafe {
|
||||||
|
$e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{}", evil!(*(0 as *const u8)));
|
||||||
|
}
|
14
src/test/ui/lint/lint-forbid-internal-unsafe.stderr
Normal file
14
src/test/ui/lint/lint-forbid-internal-unsafe.stderr
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
error: `allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
|
||||||
|
--> $DIR/lint-forbid-internal-unsafe.rs:4:1
|
||||||
|
|
|
||||||
|
LL | #[allow_internal_unsafe]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/lint-forbid-internal-unsafe.rs:1:11
|
||||||
|
|
|
||||||
|
LL | #![forbid(unsafe_code)]
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user