Migrate "unsafe_op_in_unsafe_fn" lints
This commit is contained in:
parent
82f05446a5
commit
71fe52fed0
4 changed files with 236 additions and 14 deletions
|
@ -3,3 +3,59 @@ mir_build_unconditional_recursion = function cannot return without recursing
|
||||||
.help = a `loop` may express intention better if this is on purpose
|
.help = a `loop` may express intention better if this is on purpose
|
||||||
|
|
||||||
mir_build_unconditional_recursion_call_site_label = recursive call site
|
mir_build_unconditional_recursion_call_site_label = recursive call site
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe =
|
||||||
|
call to unsafe function `{$function}` is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = consult the function's documentation for information on how to avoid undefined behavior
|
||||||
|
.label = call to unsafe function
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless =
|
||||||
|
call to unsafe function is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = consult the function's documentation for information on how to avoid undefined behavior
|
||||||
|
.label = call to unsafe function
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe =
|
||||||
|
use of inline assembly is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = inline assembly is entirely unchecked and can cause undefined behavior
|
||||||
|
.label = use of inline assembly
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe =
|
||||||
|
initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe
|
||||||
|
block (error E0133)
|
||||||
|
.note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
|
||||||
|
.label = initializing type with `rustc_layout_scalar_valid_range` attr
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe =
|
||||||
|
use of mutable static is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||||
|
.label = use of mutable static
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe =
|
||||||
|
use of extern static is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
|
||||||
|
.label = use of extern static
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe =
|
||||||
|
dereference of raw pointer is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||||
|
.label = dereference of raw pointer
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe =
|
||||||
|
access to union field is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||||
|
.label = access to union field
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe =
|
||||||
|
mutation of layout constrained field is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = mutating layout constrained fields cannot statically be checked for valid values
|
||||||
|
.label = mutation of layout constrained field
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe =
|
||||||
|
borrow of layout constrained field with interior mutability is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
|
||||||
|
.label = borrow of layout constrained field with interior mutability
|
||||||
|
|
||||||
|
mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe =
|
||||||
|
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block (error E0133)
|
||||||
|
.note = can only be called if the required target features are available
|
||||||
|
.label = call to function with `#[target_feature]`
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::build::ExprCategory;
|
use crate::build::ExprCategory;
|
||||||
|
use crate::errors::*;
|
||||||
use rustc_middle::thir::visit::{self, Visitor};
|
use rustc_middle::thir::visit::{self, Visitor};
|
||||||
|
|
||||||
use rustc_errors::struct_span_err;
|
use rustc_errors::struct_span_err;
|
||||||
|
@ -83,15 +84,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
|
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
|
||||||
SafetyContext::UnsafeFn => {
|
SafetyContext::UnsafeFn => {
|
||||||
let (description, note) = kind.description_and_note(self.tcx);
|
|
||||||
// unsafe_op_in_unsafe_fn is disallowed
|
// unsafe_op_in_unsafe_fn is disallowed
|
||||||
self.tcx.struct_span_lint_hir(
|
kind.emit_unsafe_op_in_unsafe_fn_lint(self.tcx, self.hir_context, span);
|
||||||
UNSAFE_OP_IN_UNSAFE_FN,
|
|
||||||
self.hir_context,
|
|
||||||
span,
|
|
||||||
format!("{} is unsafe and requires unsafe block (error E0133)", description,),
|
|
||||||
|lint| lint.span_label(span, kind.simple_description()).note(note),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
SafetyContext::Safe => {
|
SafetyContext::Safe => {
|
||||||
let (description, note) = kind.description_and_note(self.tcx);
|
let (description, note) = kind.description_and_note(self.tcx);
|
||||||
|
@ -536,6 +530,88 @@ enum UnsafeOpKind {
|
||||||
use UnsafeOpKind::*;
|
use UnsafeOpKind::*;
|
||||||
|
|
||||||
impl UnsafeOpKind {
|
impl UnsafeOpKind {
|
||||||
|
pub fn emit_unsafe_op_in_unsafe_fn_lint(
|
||||||
|
&self,
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
hir_id: hir::HirId,
|
||||||
|
span: Span,
|
||||||
|
) {
|
||||||
|
match self {
|
||||||
|
CallToUnsafeFunction(did) if did.is_some() => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
|
||||||
|
span,
|
||||||
|
function: &tcx.def_path_str(did.unwrap()),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
CallToUnsafeFunction(..) => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { span },
|
||||||
|
),
|
||||||
|
UseOfInlineAssembly => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeUseOfInlineAssemblyRequiresUnsafe { span },
|
||||||
|
),
|
||||||
|
InitializingTypeWith => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeInitializingTypeWithRequiresUnsafe { span },
|
||||||
|
),
|
||||||
|
UseOfMutableStatic => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeUseOfMutableStaticRequiresUnsafe { span },
|
||||||
|
),
|
||||||
|
UseOfExternStatic => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeUseOfExternStaticRequiresUnsafe { span },
|
||||||
|
),
|
||||||
|
DerefOfRawPointer => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeDerefOfRawPointerRequiresUnsafe { span },
|
||||||
|
),
|
||||||
|
AccessToUnionField => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeAccessToUnionFieldRequiresUnsafe { span },
|
||||||
|
),
|
||||||
|
MutationOfLayoutConstrainedField => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeMutationOfLayoutConstrainedFieldRequiresUnsafe { span },
|
||||||
|
),
|
||||||
|
BorrowOfLayoutConstrainedField => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeBorrowOfLayoutConstrainedFieldRequiresUnsafe { span },
|
||||||
|
),
|
||||||
|
CallToFunctionWith(did) => tcx.emit_spanned_lint(
|
||||||
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnsafeOpInUnsafeCallToFunctionWithRequiresUnsafe {
|
||||||
|
span,
|
||||||
|
function: &tcx.def_path_str(*did),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn simple_description(&self) -> &'static str {
|
pub fn simple_description(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
CallToUnsafeFunction(..) => "call to unsafe function",
|
CallToUnsafeFunction(..) => "call to unsafe function",
|
||||||
|
|
|
@ -2,12 +2,100 @@ use rustc_macros::LintDiagnostic;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
#[lint(mir_build::unconditional_recursion)]
|
#[diag(mir_build::unconditional_recursion)]
|
||||||
#[help]
|
#[help]
|
||||||
pub struct UnconditionalRecursion {
|
pub struct UnconditionalRecursion {
|
||||||
#[primary_span]
|
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label(mir_build::unconditional_recursion_call_site_label)]
|
#[label(mir_build::unconditional_recursion_call_site_label)]
|
||||||
pub call_sites: Vec<Span>,
|
pub call_sites: Vec<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
pub function: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_extern_static_requires_unsafe)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_union_field_requires_unsafe)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe)]
|
||||||
|
pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
pub function: &'a str,
|
||||||
|
}
|
||||||
|
|
|
@ -37,10 +37,12 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||||
|
|
||||||
let sp = tcx.def_span(def_id);
|
let sp = tcx.def_span(def_id);
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
tcx.emit_spanned_lint(UNCONDITIONAL_RECURSION, hir_id, sp, UnconditionalRecursion {
|
tcx.emit_spanned_lint(
|
||||||
span: sp,
|
UNCONDITIONAL_RECURSION,
|
||||||
call_sites: vis.reachable_recursive_calls,
|
hir_id,
|
||||||
});
|
sp,
|
||||||
|
UnconditionalRecursion { span: sp, call_sites: vis.reachable_recursive_calls },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue