Skip to content

Commit b7360fa

Browse files
committed
Give a specific lint for unsafety not being inherited
1 parent 2efb0cd commit b7360fa

File tree

1 file changed

+35
-9
lines changed

1 file changed

+35
-9
lines changed

compiler/rustc_mir_transform/src/check_unsafety.rs

+35-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use hir::{BlockCheckMode, ExprKind, Node};
12
use rustc_data_structures::fx::FxHashSet;
23
use rustc_errors::struct_span_err;
34
use rustc_hir as hir;
@@ -517,24 +518,49 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
517518
for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() {
518519
let (description, note) = details.description_and_note();
519520

520-
// Report an error.
521-
let unsafe_fn_msg =
522-
if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { " function or" } else { "" };
523-
524521
match kind {
525522
UnsafetyViolationKind::General => {
526523
// once
527-
struct_span_err!(
524+
// Mutable statics always require an unsafe block
525+
let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root)
526+
&& details != UnsafetyViolationDetails::UseOfMutableStatic
527+
{
528+
" function or"
529+
} else {
530+
""
531+
};
532+
533+
let mut err = struct_span_err!(
528534
tcx.sess,
529535
source_info.span,
530536
E0133,
531537
"{} is unsafe and requires unsafe{} block",
532538
description,
533539
unsafe_fn_msg,
534-
)
535-
.span_label(source_info.span, description)
536-
.note(note)
537-
.emit();
540+
);
541+
err.span_label(source_info.span, description).note(note);
542+
let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| {
543+
if let Node::Expr(block) = node
544+
&& let ExprKind::Block(block, _) = block.kind
545+
&& let BlockCheckMode::UnsafeBlock(_) = block.rules {
546+
true
547+
}
548+
else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id)
549+
&& sig.header.is_unsafe() {
550+
true
551+
} else {
552+
false
553+
}
554+
});
555+
if let Some((id, _)) = note_non_inherited {
556+
let span = tcx.hir().span(id);
557+
err.span_label(
558+
tcx.sess.source_map().guess_head_span(span),
559+
"items do not inherit unsafety from separate enclosing items",
560+
);
561+
}
562+
563+
err.emit();
538564
}
539565
UnsafetyViolationKind::UnsafeFn => tcx.struct_span_lint_hir(
540566
UNSAFE_OP_IN_UNSAFE_FN,

0 commit comments

Comments
 (0)