Skip to content

Commit 1443d1b

Browse files
lzcuntmejrs
authored andcommitted
Migrate "requires unsafe" diagnostics
1 parent 6b000cb commit 1443d1b

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
}
@@ -549,135 +535,161 @@ impl UnsafeOpKind {
549535
UNSAFE_OP_IN_UNSAFE_FN,
550536
hir_id,
551537
span,
552-
UnsafeOpInUnsafeUseOfInlineAssemblyRequiresUnsafe { span },
538+
UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { span },
553539
),
554540
InitializingTypeWith => tcx.emit_spanned_lint(
555541
UNSAFE_OP_IN_UNSAFE_FN,
556542
hir_id,
557543
span,
558-
UnsafeOpInUnsafeInitializingTypeWithRequiresUnsafe { span },
544+
UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { span },
559545
),
560546
UseOfMutableStatic => tcx.emit_spanned_lint(
561547
UNSAFE_OP_IN_UNSAFE_FN,
562548
hir_id,
563549
span,
564-
UnsafeOpInUnsafeUseOfMutableStaticRequiresUnsafe { span },
550+
UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { span },
565551
),
566552
UseOfExternStatic => tcx.emit_spanned_lint(
567553
UNSAFE_OP_IN_UNSAFE_FN,
568554
hir_id,
569555
span,
570-
UnsafeOpInUnsafeUseOfExternStaticRequiresUnsafe { span },
556+
UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { span },
571557
),
572558
DerefOfRawPointer => tcx.emit_spanned_lint(
573559
UNSAFE_OP_IN_UNSAFE_FN,
574560
hir_id,
575561
span,
576-
UnsafeOpInUnsafeDerefOfRawPointerRequiresUnsafe { span },
562+
UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { span },
577563
),
578564
AccessToUnionField => tcx.emit_spanned_lint(
579565
UNSAFE_OP_IN_UNSAFE_FN,
580566
hir_id,
581567
span,
582-
UnsafeOpInUnsafeAccessToUnionFieldRequiresUnsafe { span },
568+
UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { span },
583569
),
584570
MutationOfLayoutConstrainedField => tcx.emit_spanned_lint(
585571
UNSAFE_OP_IN_UNSAFE_FN,
586572
hir_id,
587573
span,
588-
UnsafeOpInUnsafeMutationOfLayoutConstrainedFieldRequiresUnsafe { span },
574+
UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { span },
589575
),
590576
BorrowOfLayoutConstrainedField => tcx.emit_spanned_lint(
591577
UNSAFE_OP_IN_UNSAFE_FN,
592578
hir_id,
593579
span,
594-
UnsafeOpInUnsafeBorrowOfLayoutConstrainedFieldRequiresUnsafe { span },
580+
UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { span },
595581
),
596582
CallToFunctionWith(did) => tcx.emit_spanned_lint(
597583
UNSAFE_OP_IN_UNSAFE_FN,
598584
hir_id,
599585
span,
600-
UnsafeOpInUnsafeCallToFunctionWithRequiresUnsafe {
586+
UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
601587
span,
602588
function: &tcx.def_path_str(*did),
603589
},
604590
),
605591
}
606592
}
607593

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

0 commit comments

Comments
 (0)