Skip to content

Commit 64f3e4f

Browse files
lzcuntmejrs
authored andcommitted
Migrate "requires unsafe" diagnostics
1 parent 71fe52f commit 64f3e4f

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
}
@@ -556,135 +542,161 @@ impl UnsafeOpKind {
556542
UNSAFE_OP_IN_UNSAFE_FN,
557543
hir_id,
558544
span,
559-
UnsafeOpInUnsafeUseOfInlineAssemblyRequiresUnsafe { span },
545+
UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { span },
560546
),
561547
InitializingTypeWith => tcx.emit_spanned_lint(
562548
UNSAFE_OP_IN_UNSAFE_FN,
563549
hir_id,
564550
span,
565-
UnsafeOpInUnsafeInitializingTypeWithRequiresUnsafe { span },
551+
UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { span },
566552
),
567553
UseOfMutableStatic => tcx.emit_spanned_lint(
568554
UNSAFE_OP_IN_UNSAFE_FN,
569555
hir_id,
570556
span,
571-
UnsafeOpInUnsafeUseOfMutableStaticRequiresUnsafe { span },
557+
UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { span },
572558
),
573559
UseOfExternStatic => tcx.emit_spanned_lint(
574560
UNSAFE_OP_IN_UNSAFE_FN,
575561
hir_id,
576562
span,
577-
UnsafeOpInUnsafeUseOfExternStaticRequiresUnsafe { span },
563+
UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { span },
578564
),
579565
DerefOfRawPointer => tcx.emit_spanned_lint(
580566
UNSAFE_OP_IN_UNSAFE_FN,
581567
hir_id,
582568
span,
583-
UnsafeOpInUnsafeDerefOfRawPointerRequiresUnsafe { span },
569+
UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { span },
584570
),
585571
AccessToUnionField => tcx.emit_spanned_lint(
586572
UNSAFE_OP_IN_UNSAFE_FN,
587573
hir_id,
588574
span,
589-
UnsafeOpInUnsafeAccessToUnionFieldRequiresUnsafe { span },
575+
UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { span },
590576
),
591577
MutationOfLayoutConstrainedField => tcx.emit_spanned_lint(
592578
UNSAFE_OP_IN_UNSAFE_FN,
593579
hir_id,
594580
span,
595-
UnsafeOpInUnsafeMutationOfLayoutConstrainedFieldRequiresUnsafe { span },
581+
UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { span },
596582
),
597583
BorrowOfLayoutConstrainedField => tcx.emit_spanned_lint(
598584
UNSAFE_OP_IN_UNSAFE_FN,
599585
hir_id,
600586
span,
601-
UnsafeOpInUnsafeBorrowOfLayoutConstrainedFieldRequiresUnsafe { span },
587+
UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { span },
602588
),
603589
CallToFunctionWith(did) => tcx.emit_spanned_lint(
604590
UNSAFE_OP_IN_UNSAFE_FN,
605591
hir_id,
606592
span,
607-
UnsafeOpInUnsafeCallToFunctionWithRequiresUnsafe {
593+
UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
608594
span,
609595
function: &tcx.def_path_str(*did),
610596
},
611597
),
612598
}
613599
}
614600

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

0 commit comments

Comments
 (0)