Skip to content

Commit 347c478

Browse files
authored
Rollup merge of rust-lang#103964 - clubby789:lint-enclosing-unsafe, r=compiler-errors
Give a specific lint for unsafety not being inherited In cases like ```rs static mut FOO: u64 = 0; fn main() { unsafe {static BAR: u64 = FOO;} } ``` and ```rs fn foo() { unsafe { fn bar() { unsafe_call(); } } } ``` Specifically inform the user that the unsafety is not inherited for the seperate enclosing items Fixes rust-lang#94077 r? compiler-errors `@rustbot` label +A-diagnostics
2 parents 82d7de8 + 28819cb commit 347c478

File tree

3 files changed

+84
-9
lines changed

3 files changed

+84
-9
lines changed

compiler/rustc_mir_transform/src/check_unsafety.rs

+34-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_hir as hir;
44
use rustc_hir::def_id::{DefId, LocalDefId};
55
use rustc_hir::hir_id::HirId;
66
use rustc_hir::intravisit;
7+
use rustc_hir::{BlockCheckMode, ExprKind, Node};
78
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
89
use rustc_middle::mir::*;
910
use rustc_middle::ty::query::Providers;
@@ -517,24 +518,48 @@ 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+
let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) {
525+
" function or"
526+
} else {
527+
""
528+
};
529+
530+
let mut err = struct_span_err!(
528531
tcx.sess,
529532
source_info.span,
530533
E0133,
531534
"{} is unsafe and requires unsafe{} block",
532535
description,
533536
unsafe_fn_msg,
534-
)
535-
.span_label(source_info.span, description)
536-
.note(note)
537-
.emit();
537+
);
538+
err.span_label(source_info.span, description).note(note);
539+
let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| {
540+
if let Node::Expr(block) = node
541+
&& let ExprKind::Block(block, _) = block.kind
542+
&& let BlockCheckMode::UnsafeBlock(_) = block.rules
543+
{
544+
true
545+
}
546+
else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id)
547+
&& sig.header.is_unsafe()
548+
{
549+
true
550+
} else {
551+
false
552+
}
553+
});
554+
if let Some((id, _)) = note_non_inherited {
555+
let span = tcx.hir().span(id);
556+
err.span_label(
557+
tcx.sess.source_map().guess_head_span(span),
558+
"items do not inherit unsafety from separate enclosing items",
559+
);
560+
}
561+
562+
err.emit();
538563
}
539564
UnsafetyViolationKind::UnsafeFn => tcx.struct_span_lint_hir(
540565
UNSAFE_OP_IN_UNSAFE_FN,
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#![allow(unused, dead_code)]
2+
3+
static mut FOO: u64 = 0;
4+
5+
fn static_mod() {
6+
unsafe {static BAR: u64 = FOO;}
7+
//~^ ERROR: use of mutable static is unsafe
8+
//~| NOTE: use of mutable static
9+
//~| NOTE: mutable statics can be mutated by multiple threads
10+
//~| NOTE: items do not inherit unsafety
11+
}
12+
13+
unsafe fn unsafe_call() {}
14+
fn foo() {
15+
unsafe {
16+
//~^ NOTE: items do not inherit unsafety
17+
fn bar() {
18+
unsafe_call();
19+
//~^ ERROR: call to unsafe function
20+
//~| NOTE: call to unsafe function
21+
//~| NOTE: consult the function's documentation
22+
}
23+
}
24+
}
25+
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
2+
--> $DIR/unsafe-not-inherited.rs:6:31
3+
|
4+
LL | unsafe {static BAR: u64 = FOO;}
5+
| ------ ^^^ use of mutable static
6+
| |
7+
| items do not inherit unsafety from separate enclosing items
8+
|
9+
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
10+
11+
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
12+
--> $DIR/unsafe-not-inherited.rs:18:13
13+
|
14+
LL | unsafe {
15+
| ------ items do not inherit unsafety from separate enclosing items
16+
...
17+
LL | unsafe_call();
18+
| ^^^^^^^^^^^^^ call to unsafe function
19+
|
20+
= note: consult the function's documentation for information on how to avoid undefined behavior
21+
22+
error: aborting due to 2 previous errors
23+
24+
For more information about this error, try `rustc --explain E0133`.

0 commit comments

Comments
 (0)