Skip to content

Commit

Permalink
feat: make unsafe_code lint into a lint group
Browse files Browse the repository at this point in the history
  • Loading branch information
Ezrashaw committed Mar 14, 2023
1 parent bd43458 commit dad074f
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 205 deletions.
147 changes: 7 additions & 140 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
//! `late_lint_methods!` invocation in `lib.rs`.

use crate::fluent_generated as fluent;
use crate::r#unsafe::{UNSAFE_OBLIGATION_DEFINE, UNSAFE_OBLIGATION_DISCHARGE};
use crate::{
errors::BuiltinEllpisisInclusiveRangePatterns,
lints::{
Expand All @@ -36,22 +37,21 @@ use crate::{
BuiltinTypeAliasGenericBoundsSuggestion, BuiltinTypeAliasWhereClause,
BuiltinUnexpectedCliConfigName, BuiltinUnexpectedCliConfigValue,
BuiltinUngatedAsyncFnTrackCaller, BuiltinUnnameableTestItems, BuiltinUnpermittedTypeInit,
BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe,
BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
BuiltinWhileTrue, SuggestChangingAssocTypes,
BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnstableFeatures,
BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, BuiltinWhileTrue,
SuggestChangingAssocTypes,
},
types::{transparent_newtype_field, CItemKind},
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
};
use hir::IsAsync;
use rustc_ast::attr;
use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::visit::{FnCtxt, FnKind};
use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust::{self, expr_to_string};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Applicability, DecorateLint, MultiSpan};
use rustc_errors::{Applicability, MultiSpan};
use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
Expand Down Expand Up @@ -287,140 +287,6 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
}
}

declare_lint! {
/// The `unsafe_code` lint catches usage of `unsafe` code.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(unsafe_code)]
/// fn main() {
/// unsafe {
///
/// }
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// This lint is intended to restrict the usage of `unsafe`, which can be
/// difficult to use correctly.
UNSAFE_CODE,
Allow,
"usage of `unsafe` code"
}

declare_lint_pass!(UnsafeCode => [UNSAFE_CODE]);

impl UnsafeCode {
fn report_unsafe(
&self,
cx: &EarlyContext<'_>,
span: Span,
decorate: impl for<'a> DecorateLint<'a, ()>,
) {
// This comes from a macro that has `#[allow_internal_unsafe]`.
if span.allows_unsafe() {
return;
}

cx.emit_spanned_lint(UNSAFE_CODE, span, decorate);
}
}

impl EarlyLintPass for UnsafeCode {
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
if attr.has_name(sym::allow_internal_unsafe) {
self.report_unsafe(cx, attr.span, BuiltinUnsafe::AllowInternalUnsafe);
}
}

#[inline]
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
if let ast::ExprKind::Block(ref blk, _) = e.kind {
// Don't warn about generated blocks; that'll just pollute the output.
if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
self.report_unsafe(cx, blk.span, BuiltinUnsafe::UnsafeBlock);
}
}
}

fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
match it.kind {
ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => {
self.report_unsafe(cx, it.span, BuiltinUnsafe::UnsafeTrait);
}

ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => {
self.report_unsafe(cx, it.span, BuiltinUnsafe::UnsafeImpl);
}

ast::ItemKind::Fn(..) => {
if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) {
self.report_unsafe(cx, attr.span, BuiltinUnsafe::NoMangleFn);
}

if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::export_name) {
self.report_unsafe(cx, attr.span, BuiltinUnsafe::ExportNameFn);
}

if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::link_section) {
self.report_unsafe(cx, attr.span, BuiltinUnsafe::LinkSectionFn);
}
}

ast::ItemKind::Static(..) => {
if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) {
self.report_unsafe(cx, attr.span, BuiltinUnsafe::NoMangleStatic);
}

if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::export_name) {
self.report_unsafe(cx, attr.span, BuiltinUnsafe::ExportNameStatic);
}

if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::link_section) {
self.report_unsafe(cx, attr.span, BuiltinUnsafe::LinkSectionStatic);
}
}

_ => {}
}
}

fn check_impl_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
if let ast::AssocItemKind::Fn(..) = it.kind {
if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) {
self.report_unsafe(cx, attr.span, BuiltinUnsafe::NoMangleMethod);
}
if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::export_name) {
self.report_unsafe(cx, attr.span, BuiltinUnsafe::ExportNameMethod);
}
}
}

fn check_fn(&mut self, cx: &EarlyContext<'_>, fk: FnKind<'_>, span: Span, _: ast::NodeId) {
if let FnKind::Fn(
ctxt,
_,
ast::FnSig { header: ast::FnHeader { unsafety: ast::Unsafe::Yes(_), .. }, .. },
_,
_,
body,
) = fk
{
let decorator = match ctxt {
FnCtxt::Foreign => return,
FnCtxt::Free => BuiltinUnsafe::DeclUnsafeFn,
FnCtxt::Assoc(_) if body.is_none() => BuiltinUnsafe::DeclUnsafeMethod,
FnCtxt::Assoc(_) => BuiltinUnsafe::ImplUnsafeMethod,
};
self.report_unsafe(cx, span, decorator);
}
}
}

declare_lint! {
/// The `missing_docs` lint detects missing documentation for public items.
///
Expand Down Expand Up @@ -1633,7 +1499,8 @@ declare_lint_pass!(
WHILE_TRUE,
BOX_POINTERS,
NON_SHORTHAND_FIELD_PATTERNS,
UNSAFE_CODE,
UNSAFE_OBLIGATION_DEFINE,
UNSAFE_OBLIGATION_DISCHARGE,
MISSING_DOCS,
MISSING_COPY_IMPLEMENTATIONS,
MISSING_DEBUG_IMPLEMENTATIONS,
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ mod passes;
mod redundant_semicolon;
mod traits;
mod types;
mod r#unsafe;
mod unused;

pub use array_into_iter::ARRAY_INTO_ITER;
Expand All @@ -92,6 +93,7 @@ use rustc_session::lint::builtin::{
};
use rustc_span::symbol::Ident;
use rustc_span::Span;
use r#unsafe::UnsafeCode;

use array_into_iter::ArrayIntoIter;
use builtin::*;
Expand Down Expand Up @@ -126,6 +128,8 @@ pub use rustc_session::lint::Level::{self, *};
pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId};
pub use rustc_session::lint::{LintArray, LintPass};

use crate::r#unsafe::{UNSAFE_OBLIGATION_DEFINE, UNSAFE_OBLIGATION_DISCHARGE};

fluent_messages! { "../messages.ftl" }

pub fn provide(providers: &mut Providers) {
Expand Down Expand Up @@ -272,6 +276,8 @@ fn register_builtins(store: &mut LintStore) {
store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints());
store.register_lints(&BuiltinCombinedLateLintPass::get_lints());

add_lint_group!("unsafe_code", UNSAFE_OBLIGATION_DEFINE, UNSAFE_OBLIGATION_DISCHARGE);

add_lint_group!(
"nonstandard_style",
NON_CAMEL_CASE_TYPES,
Expand Down
Loading

0 comments on commit dad074f

Please sign in to comment.