Skip to content

Commit 71fe52f

Browse files
lzcuntmejrs
authored andcommitted
Migrate "unsafe_op_in_unsafe_fn" lints
1 parent 82f0544 commit 71fe52f

File tree

4 files changed

+236
-14
lines changed

4 files changed

+236
-14
lines changed

compiler/rustc_error_messages/locales/en-US/mir_build.ftl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,59 @@ mir_build_unconditional_recursion = function cannot return without recursing
33
.help = a `loop` may express intention better if this is on purpose
44
55
mir_build_unconditional_recursion_call_site_label = recursive call site
6+
7+
mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe =
8+
call to unsafe function `{$function}` is unsafe and requires unsafe block (error E0133)
9+
.note = consult the function's documentation for information on how to avoid undefined behavior
10+
.label = call to unsafe function
11+
12+
mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless =
13+
call to unsafe function is unsafe and requires unsafe block (error E0133)
14+
.note = consult the function's documentation for information on how to avoid undefined behavior
15+
.label = call to unsafe function
16+
17+
mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe =
18+
use of inline assembly is unsafe and requires unsafe block (error E0133)
19+
.note = inline assembly is entirely unchecked and can cause undefined behavior
20+
.label = use of inline assembly
21+
22+
mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe =
23+
initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe
24+
block (error E0133)
25+
.note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
26+
.label = initializing type with `rustc_layout_scalar_valid_range` attr
27+
28+
mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe =
29+
use of mutable static is unsafe and requires unsafe block (error E0133)
30+
.note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
31+
.label = use of mutable static
32+
33+
mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe =
34+
use of extern static is unsafe and requires unsafe block (error E0133)
35+
.note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
36+
.label = use of extern static
37+
38+
mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe =
39+
dereference of raw pointer is unsafe and requires unsafe block (error E0133)
40+
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
41+
.label = dereference of raw pointer
42+
43+
mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe =
44+
access to union field is unsafe and requires unsafe block (error E0133)
45+
.note = the field may not be properly initialized: using uninitialized data will cause undefined behavior
46+
.label = access to union field
47+
48+
mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe =
49+
mutation of layout constrained field is unsafe and requires unsafe block (error E0133)
50+
.note = mutating layout constrained fields cannot statically be checked for valid values
51+
.label = mutation of layout constrained field
52+
53+
mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe =
54+
borrow of layout constrained field with interior mutability is unsafe and requires unsafe block (error E0133)
55+
.note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
56+
.label = borrow of layout constrained field with interior mutability
57+
58+
mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe =
59+
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block (error E0133)
60+
.note = can only be called if the required target features are available
61+
.label = call to function with `#[target_feature]`

compiler/rustc_mir_build/src/check_unsafety.rs

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::build::ExprCategory;
2+
use crate::errors::*;
23
use rustc_middle::thir::visit::{self, Visitor};
34

45
use rustc_errors::struct_span_err;
@@ -83,15 +84,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
8384
}
8485
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
8586
SafetyContext::UnsafeFn => {
86-
let (description, note) = kind.description_and_note(self.tcx);
8787
// unsafe_op_in_unsafe_fn is disallowed
88-
self.tcx.struct_span_lint_hir(
89-
UNSAFE_OP_IN_UNSAFE_FN,
90-
self.hir_context,
91-
span,
92-
format!("{} is unsafe and requires unsafe block (error E0133)", description,),
93-
|lint| lint.span_label(span, kind.simple_description()).note(note),
94-
)
88+
kind.emit_unsafe_op_in_unsafe_fn_lint(self.tcx, self.hir_context, span);
9589
}
9690
SafetyContext::Safe => {
9791
let (description, note) = kind.description_and_note(self.tcx);
@@ -536,6 +530,88 @@ enum UnsafeOpKind {
536530
use UnsafeOpKind::*;
537531

538532
impl UnsafeOpKind {
533+
pub fn emit_unsafe_op_in_unsafe_fn_lint(
534+
&self,
535+
tcx: TyCtxt<'_>,
536+
hir_id: hir::HirId,
537+
span: Span,
538+
) {
539+
match self {
540+
CallToUnsafeFunction(did) if did.is_some() => tcx.emit_spanned_lint(
541+
UNSAFE_OP_IN_UNSAFE_FN,
542+
hir_id,
543+
span,
544+
UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
545+
span,
546+
function: &tcx.def_path_str(did.unwrap()),
547+
},
548+
),
549+
CallToUnsafeFunction(..) => tcx.emit_spanned_lint(
550+
UNSAFE_OP_IN_UNSAFE_FN,
551+
hir_id,
552+
span,
553+
UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { span },
554+
),
555+
UseOfInlineAssembly => tcx.emit_spanned_lint(
556+
UNSAFE_OP_IN_UNSAFE_FN,
557+
hir_id,
558+
span,
559+
UnsafeOpInUnsafeUseOfInlineAssemblyRequiresUnsafe { span },
560+
),
561+
InitializingTypeWith => tcx.emit_spanned_lint(
562+
UNSAFE_OP_IN_UNSAFE_FN,
563+
hir_id,
564+
span,
565+
UnsafeOpInUnsafeInitializingTypeWithRequiresUnsafe { span },
566+
),
567+
UseOfMutableStatic => tcx.emit_spanned_lint(
568+
UNSAFE_OP_IN_UNSAFE_FN,
569+
hir_id,
570+
span,
571+
UnsafeOpInUnsafeUseOfMutableStaticRequiresUnsafe { span },
572+
),
573+
UseOfExternStatic => tcx.emit_spanned_lint(
574+
UNSAFE_OP_IN_UNSAFE_FN,
575+
hir_id,
576+
span,
577+
UnsafeOpInUnsafeUseOfExternStaticRequiresUnsafe { span },
578+
),
579+
DerefOfRawPointer => tcx.emit_spanned_lint(
580+
UNSAFE_OP_IN_UNSAFE_FN,
581+
hir_id,
582+
span,
583+
UnsafeOpInUnsafeDerefOfRawPointerRequiresUnsafe { span },
584+
),
585+
AccessToUnionField => tcx.emit_spanned_lint(
586+
UNSAFE_OP_IN_UNSAFE_FN,
587+
hir_id,
588+
span,
589+
UnsafeOpInUnsafeAccessToUnionFieldRequiresUnsafe { span },
590+
),
591+
MutationOfLayoutConstrainedField => tcx.emit_spanned_lint(
592+
UNSAFE_OP_IN_UNSAFE_FN,
593+
hir_id,
594+
span,
595+
UnsafeOpInUnsafeMutationOfLayoutConstrainedFieldRequiresUnsafe { span },
596+
),
597+
BorrowOfLayoutConstrainedField => tcx.emit_spanned_lint(
598+
UNSAFE_OP_IN_UNSAFE_FN,
599+
hir_id,
600+
span,
601+
UnsafeOpInUnsafeBorrowOfLayoutConstrainedFieldRequiresUnsafe { span },
602+
),
603+
CallToFunctionWith(did) => tcx.emit_spanned_lint(
604+
UNSAFE_OP_IN_UNSAFE_FN,
605+
hir_id,
606+
span,
607+
UnsafeOpInUnsafeCallToFunctionWithRequiresUnsafe {
608+
span,
609+
function: &tcx.def_path_str(*did),
610+
},
611+
),
612+
}
613+
}
614+
539615
pub fn simple_description(&self) -> &'static str {
540616
match self {
541617
CallToUnsafeFunction(..) => "call to unsafe function",

compiler/rustc_mir_build/src/errors.rs

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,100 @@ use rustc_macros::LintDiagnostic;
22
use rustc_span::Span;
33

44
#[derive(LintDiagnostic)]
5-
#[lint(mir_build::unconditional_recursion)]
5+
#[diag(mir_build::unconditional_recursion)]
66
#[help]
77
pub struct UnconditionalRecursion {
8-
#[primary_span]
98
#[label]
109
pub span: Span,
1110
#[label(mir_build::unconditional_recursion_call_site_label)]
1211
pub call_sites: Vec<Span>,
1312
}
13+
14+
#[derive(LintDiagnostic)]
15+
#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)]
16+
#[note]
17+
pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> {
18+
#[label]
19+
pub span: Span,
20+
pub function: &'a str,
21+
}
22+
23+
#[derive(LintDiagnostic)]
24+
#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)]
25+
#[note]
26+
pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless {
27+
#[label]
28+
pub span: Span,
29+
}
30+
31+
#[derive(LintDiagnostic)]
32+
#[diag(mir_build::unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe)]
33+
#[note]
34+
pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe {
35+
#[label]
36+
pub span: Span,
37+
}
38+
39+
#[derive(LintDiagnostic)]
40+
#[diag(mir_build::unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe)]
41+
#[note]
42+
pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
43+
#[label]
44+
pub span: Span,
45+
}
46+
47+
#[derive(LintDiagnostic)]
48+
#[diag(mir_build::unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe)]
49+
#[note]
50+
pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
51+
#[label]
52+
pub span: Span,
53+
}
54+
55+
#[derive(LintDiagnostic)]
56+
#[diag(mir_build::unsafe_op_in_unsafe_fn_extern_static_requires_unsafe)]
57+
#[note]
58+
pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe {
59+
#[label]
60+
pub span: Span,
61+
}
62+
63+
#[derive(LintDiagnostic)]
64+
#[diag(mir_build::unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe)]
65+
#[note]
66+
pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe {
67+
#[label]
68+
pub span: Span,
69+
}
70+
71+
#[derive(LintDiagnostic)]
72+
#[diag(mir_build::unsafe_op_in_unsafe_fn_union_field_requires_unsafe)]
73+
#[note]
74+
pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe {
75+
#[label]
76+
pub span: Span,
77+
}
78+
79+
#[derive(LintDiagnostic)]
80+
#[diag(mir_build::unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe)]
81+
#[note]
82+
pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe {
83+
#[label]
84+
pub span: Span,
85+
}
86+
87+
#[derive(LintDiagnostic)]
88+
#[diag(mir_build::unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe)]
89+
pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe {
90+
#[label]
91+
pub span: Span,
92+
}
93+
94+
#[derive(LintDiagnostic)]
95+
#[diag(mir_build::unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)]
96+
#[note]
97+
pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> {
98+
#[label]
99+
pub span: Span,
100+
pub function: &'a str,
101+
}

compiler/rustc_mir_build/src/lints.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
3737

3838
let sp = tcx.def_span(def_id);
3939
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
40-
tcx.emit_spanned_lint(UNCONDITIONAL_RECURSION, hir_id, sp, UnconditionalRecursion {
41-
span: sp,
42-
call_sites: vis.reachable_recursive_calls,
43-
});
40+
tcx.emit_spanned_lint(
41+
UNCONDITIONAL_RECURSION,
42+
hir_id,
43+
sp,
44+
UnconditionalRecursion { span: sp, call_sites: vis.reachable_recursive_calls },
45+
);
4446
}
4547
}
4648

0 commit comments

Comments
 (0)