diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 80e1246ec6bf3..269d9f3b102c1 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -1,10 +1,10 @@ -use hir::{BlockCheckMode, ExprKind, Node}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::HirId; use rustc_hir::intravisit; +use rustc_hir::{BlockCheckMode, ExprKind, Node}; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::query::Providers; @@ -521,10 +521,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { match kind { UnsafetyViolationKind::General => { // once - // Mutable statics always require an unsafe block - let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) - && details != UnsafetyViolationDetails::UseOfMutableStatic - { + let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { " function or" } else { "" @@ -542,12 +539,14 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| { if let Node::Expr(block) = node && let ExprKind::Block(block, _) = block.kind - && let BlockCheckMode::UnsafeBlock(_) = block.rules { - true - } + && let BlockCheckMode::UnsafeBlock(_) = block.rules + { + true + } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) - && sig.header.is_unsafe() { - true + && sig.header.is_unsafe() + { + true } else { false } diff --git a/src/test/ui/unsafe/unsafe-not-inherited.rs b/src/test/ui/unsafe/unsafe-not-inherited.rs new file mode 100644 index 0000000000000..6d797caa0f94d --- /dev/null +++ b/src/test/ui/unsafe/unsafe-not-inherited.rs @@ -0,0 +1,26 @@ +#![allow(unused, dead_code)] + +static mut FOO: u64 = 0; + +fn static_mod() { + unsafe {static BAR: u64 = FOO;} + //~^ ERROR: use of mutable static is unsafe + //~| NOTE: use of mutable static + //~| NOTE: mutable statics can be mutated by multiple threads + //~| NOTE: items do not inherit unsafety +} + +unsafe fn unsafe_call() {} +fn foo() { + unsafe { + //~^ NOTE: items do not inherit unsafety + fn bar() { + unsafe_call(); + //~^ ERROR: call to unsafe function + //~| NOTE: call to unsafe function + //~| NOTE: consult the function's documentation + } + } +} + +fn main() {} diff --git a/src/test/ui/unsafe/unsafe-not-inherited.stderr b/src/test/ui/unsafe/unsafe-not-inherited.stderr new file mode 100644 index 0000000000000..3bc5ca5c9d151 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-not-inherited.stderr @@ -0,0 +1,24 @@ +error[E0133]: use of mutable static is unsafe and requires unsafe function or block + --> $DIR/unsafe-not-inherited.rs:6:31 + | +LL | unsafe {static BAR: u64 = FOO;} + | ------ ^^^ use of mutable static + | | + | items do not inherit unsafety from separate enclosing items + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/unsafe-not-inherited.rs:18:13 + | +LL | unsafe { + | ------ items do not inherit unsafety from separate enclosing items +... +LL | unsafe_call(); + | ^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0133`.