Skip to content

Commit eb7b30f

Browse files
committed
Migrate "requires unsafe" diagnostics
1 parent b331f81 commit eb7b30f

File tree

3 files changed

+431
-95
lines changed

3 files changed

+431
-95
lines changed

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

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,113 @@ mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe =
5959
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block (error E0133)
6060
.note = can only be called if the required target features are available
6161
.label = call to function with `#[target_feature]`
62+
63+
mir_build_call_to_unsafe_fn_requires_unsafe =
64+
call to unsafe function `{$function}` is unsafe and requires unsafe block
65+
.note = consult the function's documentation for information on how to avoid undefined behavior
66+
.label = call to unsafe function
67+
68+
mir_build_call_to_unsafe_fn_requires_unsafe_nameless =
69+
call to unsafe function is unsafe and requires unsafe block
70+
.note = consult the function's documentation for information on how to avoid undefined behavior
71+
.label = call to unsafe function
72+
73+
mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
74+
call to unsafe function `{$function}` is unsafe and requires unsafe function or block
75+
.note = consult the function's documentation for information on how to avoid undefined behavior
76+
.label = call to unsafe function
77+
78+
mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed =
79+
call to unsafe function is unsafe and requires unsafe function or block
80+
.note = consult the function's documentation for information on how to avoid undefined behavior
81+
.label = call to unsafe function
82+
83+
mir_build_inline_assembly_requires_unsafe =
84+
use of inline assembly is unsafe and requires unsafe block
85+
.note = inline assembly is entirely unchecked and can cause undefined behavior
86+
.label = use of inline assembly
87+
88+
mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
89+
use of inline assembly is unsafe and requires unsafe function or block
90+
.note = inline assembly is entirely unchecked and can cause undefined behavior
91+
.label = use of inline assembly
92+
93+
mir_build_initializing_type_with_requires_unsafe =
94+
initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe block
95+
.note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
96+
.label = initializing type with `rustc_layout_scalar_valid_range` attr
97+
98+
mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
99+
initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block
100+
.note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
101+
.label = initializing type with `rustc_layout_scalar_valid_range` attr
102+
103+
mir_build_mutable_static_requires_unsafe =
104+
use of mutable static is unsafe and requires unsafe block
105+
.note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
106+
.label = use of mutable static
107+
108+
mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
109+
use of mutable static is unsafe and requires unsafe function or block
110+
.note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
111+
.label = use of mutable static
112+
113+
mir_build_extern_static_requires_unsafe =
114+
use of extern static is unsafe and requires unsafe block
115+
.note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
116+
.label = use of extern static
117+
118+
mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
119+
use of extern static is unsafe and requires unsafe function or block
120+
.note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
121+
.label = use of extern static
122+
123+
mir_build_deref_raw_pointer_requires_unsafe =
124+
dereference of raw pointer is unsafe and requires unsafe block
125+
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
126+
.label = dereference of raw pointer
127+
128+
mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
129+
dereference of raw pointer is unsafe and requires unsafe function or block
130+
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
131+
.label = dereference of raw pointer
132+
133+
mir_build_union_field_requires_unsafe =
134+
access to union field is unsafe and requires unsafe block
135+
.note = the field may not be properly initialized: using uninitialized data will cause undefined behavior
136+
.label = access to union field
137+
138+
mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
139+
access to union field is unsafe and requires unsafe function or block
140+
.note = the field may not be properly initialized: using uninitialized data will cause undefined behavior
141+
.label = access to union field
142+
143+
mir_build_mutation_of_layout_constrained_field_requires_unsafe =
144+
mutation of layout constrained field is unsafe and requires unsafe block
145+
.note = mutating layout constrained fields cannot statically be checked for valid values
146+
.label = mutation of layout constrained field
147+
148+
mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
149+
mutation of layout constrained field is unsafe and requires unsafe function or block
150+
.note = mutating layout constrained fields cannot statically be checked for valid values
151+
.label = mutation of layout constrained field
152+
153+
mir_build_borrow_of_layout_constrained_field_requires_unsafe =
154+
borrow of layout constrained field with interior mutability is unsafe and requires unsafe block
155+
.note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
156+
.label = borrow of layout constrained field with interior mutability
157+
158+
mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
159+
borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
160+
.note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
161+
.label = borrow of layout constrained field with interior mutability
162+
163+
mir_build_call_to_fn_with_requires_unsafe =
164+
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block
165+
.note = can only be called if the required target features are available
166+
.label = call to function with `#[target_feature]`
167+
168+
mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
169+
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe function or block
170+
.note = can only be called if the required target features are available
171+
.label = call to function with `#[target_feature]`

compiler/rustc_mir_build/src/check_unsafety.rs

Lines changed: 106 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use crate::build::ExprCategory;
22
use crate::errors::*;
33
use rustc_middle::thir::visit::{self, Visitor};
44

5-
use rustc_errors::struct_span_err;
65
use rustc_hir as hir;
76
use rustc_middle::mir::BorrowKind;
87
use rustc_middle::thir::*;
@@ -13,7 +12,6 @@ use rustc_span::def_id::{DefId, LocalDefId};
1312
use rustc_span::symbol::Symbol;
1413
use rustc_span::Span;
1514

16-
use std::borrow::Cow;
1715
use std::ops::Bound;
1816

1917
struct UnsafetyVisitor<'a, 'tcx> {
@@ -88,19 +86,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
8886
kind.emit_unsafe_op_in_unsafe_fn_lint(self.tcx, self.hir_context, span);
8987
}
9088
SafetyContext::Safe => {
91-
let (description, note) = kind.description_and_note(self.tcx);
92-
let fn_sugg = if unsafe_op_in_unsafe_fn_allowed { " function or" } else { "" };
93-
struct_span_err!(
94-
self.tcx.sess,
95-
span,
96-
E0133,
97-
"{} is unsafe and requires unsafe{} block",
98-
description,
99-
fn_sugg,
100-
)
101-
.span_label(span, kind.simple_description())
102-
.note(note)
103-
.emit();
89+
kind.emit_requires_unsafe_err(self.tcx, span, unsafe_op_in_unsafe_fn_allowed);
10490
}
10591
}
10692
}
@@ -552,135 +538,161 @@ impl UnsafeOpKind {
552538
UNSAFE_OP_IN_UNSAFE_FN,
553539
hir_id,
554540
span,
555-
UnsafeOpInUnsafeUseOfInlineAssemblyRequiresUnsafe { span },
541+
UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { span },
556542
),
557543
InitializingTypeWith => tcx.emit_spanned_lint(
558544
UNSAFE_OP_IN_UNSAFE_FN,
559545
hir_id,
560546
span,
561-
UnsafeOpInUnsafeInitializingTypeWithRequiresUnsafe { span },
547+
UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { span },
562548
),
563549
UseOfMutableStatic => tcx.emit_spanned_lint(
564550
UNSAFE_OP_IN_UNSAFE_FN,
565551
hir_id,
566552
span,
567-
UnsafeOpInUnsafeUseOfMutableStaticRequiresUnsafe { span },
553+
UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { span },
568554
),
569555
UseOfExternStatic => tcx.emit_spanned_lint(
570556
UNSAFE_OP_IN_UNSAFE_FN,
571557
hir_id,
572558
span,
573-
UnsafeOpInUnsafeUseOfExternStaticRequiresUnsafe { span },
559+
UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { span },
574560
),
575561
DerefOfRawPointer => tcx.emit_spanned_lint(
576562
UNSAFE_OP_IN_UNSAFE_FN,
577563
hir_id,
578564
span,
579-
UnsafeOpInUnsafeDerefOfRawPointerRequiresUnsafe { span },
565+
UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { span },
580566
),
581567
AccessToUnionField => tcx.emit_spanned_lint(
582568
UNSAFE_OP_IN_UNSAFE_FN,
583569
hir_id,
584570
span,
585-
UnsafeOpInUnsafeAccessToUnionFieldRequiresUnsafe { span },
571+
UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { span },
586572
),
587573
MutationOfLayoutConstrainedField => tcx.emit_spanned_lint(
588574
UNSAFE_OP_IN_UNSAFE_FN,
589575
hir_id,
590576
span,
591-
UnsafeOpInUnsafeMutationOfLayoutConstrainedFieldRequiresUnsafe { span },
577+
UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { span },
592578
),
593579
BorrowOfLayoutConstrainedField => tcx.emit_spanned_lint(
594580
UNSAFE_OP_IN_UNSAFE_FN,
595581
hir_id,
596582
span,
597-
UnsafeOpInUnsafeBorrowOfLayoutConstrainedFieldRequiresUnsafe { span },
583+
UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { span },
598584
),
599585
CallToFunctionWith(did) => tcx.emit_spanned_lint(
600586
UNSAFE_OP_IN_UNSAFE_FN,
601587
hir_id,
602588
span,
603-
UnsafeOpInUnsafeCallToFunctionWithRequiresUnsafe {
589+
UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
604590
span,
605591
function: &tcx.def_path_str(*did),
606592
},
607593
),
608594
}
609595
}
610596

611-
pub fn simple_description(&self) -> &'static str {
597+
pub fn emit_requires_unsafe_err(
598+
&self,
599+
tcx: TyCtxt<'_>,
600+
span: Span,
601+
unsafe_op_in_unsafe_fn_allowed: bool,
602+
) {
612603
match self {
613-
CallToUnsafeFunction(..) => "call to unsafe function",
614-
UseOfInlineAssembly => "use of inline assembly",
615-
InitializingTypeWith => "initializing type with `rustc_layout_scalar_valid_range` attr",
616-
UseOfMutableStatic => "use of mutable static",
617-
UseOfExternStatic => "use of extern static",
618-
DerefOfRawPointer => "dereference of raw pointer",
619-
AccessToUnionField => "access to union field",
620-
MutationOfLayoutConstrainedField => "mutation of layout constrained field",
604+
CallToUnsafeFunction(did) if did.is_some() && unsafe_op_in_unsafe_fn_allowed => {
605+
tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
606+
span,
607+
function: &tcx.def_path_str(did.unwrap()),
608+
});
609+
}
610+
CallToUnsafeFunction(did) if did.is_some() => {
611+
tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafe {
612+
span,
613+
function: &tcx.def_path_str(did.unwrap()),
614+
});
615+
}
616+
CallToUnsafeFunction(..) if unsafe_op_in_unsafe_fn_allowed => {
617+
tcx.sess.emit_err(
618+
CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { span },
619+
);
620+
}
621+
CallToUnsafeFunction(..) => {
622+
tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeNameless { span });
623+
}
624+
UseOfInlineAssembly if unsafe_op_in_unsafe_fn_allowed => {
625+
tcx.sess
626+
.emit_err(UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
627+
}
628+
UseOfInlineAssembly => {
629+
tcx.sess.emit_err(UseOfInlineAssemblyRequiresUnsafe { span });
630+
}
631+
InitializingTypeWith if unsafe_op_in_unsafe_fn_allowed => {
632+
tcx.sess
633+
.emit_err(InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
634+
}
635+
InitializingTypeWith => {
636+
tcx.sess.emit_err(InitializingTypeWithRequiresUnsafe { span });
637+
}
638+
UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => {
639+
tcx.sess
640+
.emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
641+
}
642+
UseOfMutableStatic => {
643+
tcx.sess.emit_err(UseOfMutableStaticRequiresUnsafe { span });
644+
}
645+
UseOfExternStatic if unsafe_op_in_unsafe_fn_allowed => {
646+
tcx.sess
647+
.emit_err(UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
648+
}
649+
UseOfExternStatic => {
650+
tcx.sess.emit_err(UseOfExternStaticRequiresUnsafe { span });
651+
}
652+
DerefOfRawPointer if unsafe_op_in_unsafe_fn_allowed => {
653+
tcx.sess
654+
.emit_err(DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
655+
}
656+
DerefOfRawPointer => {
657+
tcx.sess.emit_err(DerefOfRawPointerRequiresUnsafe { span });
658+
}
659+
AccessToUnionField if unsafe_op_in_unsafe_fn_allowed => {
660+
tcx.sess
661+
.emit_err(AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
662+
}
663+
AccessToUnionField => {
664+
tcx.sess.emit_err(AccessToUnionFieldRequiresUnsafe { span });
665+
}
666+
MutationOfLayoutConstrainedField if unsafe_op_in_unsafe_fn_allowed => {
667+
tcx.sess.emit_err(
668+
MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
669+
span,
670+
},
671+
);
672+
}
673+
MutationOfLayoutConstrainedField => {
674+
tcx.sess.emit_err(MutationOfLayoutConstrainedFieldRequiresUnsafe { span });
675+
}
676+
BorrowOfLayoutConstrainedField if unsafe_op_in_unsafe_fn_allowed => {
677+
tcx.sess.emit_err(
678+
BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span },
679+
);
680+
}
621681
BorrowOfLayoutConstrainedField => {
622-
"borrow of layout constrained field with interior mutability"
682+
tcx.sess.emit_err(BorrowOfLayoutConstrainedFieldRequiresUnsafe { span });
683+
}
684+
CallToFunctionWith(did) if unsafe_op_in_unsafe_fn_allowed => {
685+
tcx.sess.emit_err(CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
686+
span,
687+
function: &tcx.def_path_str(*did),
688+
});
689+
}
690+
CallToFunctionWith(did) => {
691+
tcx.sess.emit_err(CallToFunctionWithRequiresUnsafe {
692+
span,
693+
function: &tcx.def_path_str(*did),
694+
});
623695
}
624-
CallToFunctionWith(..) => "call to function with `#[target_feature]`",
625-
}
626-
}
627-
628-
pub fn description_and_note(&self, tcx: TyCtxt<'_>) -> (Cow<'static, str>, &'static str) {
629-
match self {
630-
CallToUnsafeFunction(did) => (
631-
if let Some(did) = did {
632-
Cow::from(format!("call to unsafe function `{}`", tcx.def_path_str(*did)))
633-
} else {
634-
Cow::Borrowed(self.simple_description())
635-
},
636-
"consult the function's documentation for information on how to avoid undefined \
637-
behavior",
638-
),
639-
UseOfInlineAssembly => (
640-
Cow::Borrowed(self.simple_description()),
641-
"inline assembly is entirely unchecked and can cause undefined behavior",
642-
),
643-
InitializingTypeWith => (
644-
Cow::Borrowed(self.simple_description()),
645-
"initializing a layout restricted type's field with a value outside the valid \
646-
range is undefined behavior",
647-
),
648-
UseOfMutableStatic => (
649-
Cow::Borrowed(self.simple_description()),
650-
"mutable statics can be mutated by multiple threads: aliasing violations or data \
651-
races will cause undefined behavior",
652-
),
653-
UseOfExternStatic => (
654-
Cow::Borrowed(self.simple_description()),
655-
"extern statics are not controlled by the Rust type system: invalid data, \
656-
aliasing violations or data races will cause undefined behavior",
657-
),
658-
DerefOfRawPointer => (
659-
Cow::Borrowed(self.simple_description()),
660-
"raw pointers may be null, dangling or unaligned; they can violate aliasing rules \
661-
and cause data races: all of these are undefined behavior",
662-
),
663-
AccessToUnionField => (
664-
Cow::Borrowed(self.simple_description()),
665-
"the field may not be properly initialized: using uninitialized data will cause \
666-
undefined behavior",
667-
),
668-
MutationOfLayoutConstrainedField => (
669-
Cow::Borrowed(self.simple_description()),
670-
"mutating layout constrained fields cannot statically be checked for valid values",
671-
),
672-
BorrowOfLayoutConstrainedField => (
673-
Cow::Borrowed(self.simple_description()),
674-
"references to fields of layout constrained fields lose the constraints. Coupled \
675-
with interior mutability, the field can be changed to invalid values",
676-
),
677-
CallToFunctionWith(did) => (
678-
Cow::from(format!(
679-
"call to function `{}` with `#[target_feature]`",
680-
tcx.def_path_str(*did)
681-
)),
682-
"can only be called if the required target features are available",
683-
),
684696
}
685697
}
686698
}

0 commit comments

Comments
 (0)