diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index bac47d0b547..f0472758dfb 100644 --- a/compiler/rustc_mir/src/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs @@ -568,24 +568,23 @@ fn is_enclosed( tcx: TyCtxt<'_>, used_unsafe: &FxHashSet, id: hir::HirId, -) -> Option<(String, hir::HirId)> { + unsafe_op_in_unsafe_fn_allowed: bool, +) -> Option<(&'static str, hir::HirId)> { let parent_id = tcx.hir().get_parent_node(id); if parent_id != id { if used_unsafe.contains(&parent_id) { - Some(("block".to_string(), parent_id)) + Some(("block", parent_id)) } else if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref sig, _, _), .. })) = tcx.hir().find(parent_id) { - if sig.header.unsafety == hir::Unsafety::Unsafe - && !tcx.features().unsafe_block_in_unsafe_fn - { - Some(("fn".to_string(), parent_id)) + if sig.header.unsafety == hir::Unsafety::Unsafe && unsafe_op_in_unsafe_fn_allowed { + Some(("fn", parent_id)) } else { None } } else { - is_enclosed(tcx, used_unsafe, parent_id) + is_enclosed(tcx, used_unsafe, parent_id, unsafe_op_in_unsafe_fn_allowed) } } else { None @@ -598,7 +597,9 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, used_unsafe: &FxHashSet, id let msg = "unnecessary `unsafe` block"; let mut db = lint.build(msg); db.span_label(span, msg); - if let Some((kind, id)) = is_enclosed(tcx, used_unsafe, id) { + if let Some((kind, id)) = + is_enclosed(tcx, used_unsafe, id, unsafe_op_in_unsafe_fn_allowed(tcx, id)) + { db.span_label( tcx.sess.source_map().guess_head_span(tcx.hir().span(id)), format!("because it's nested under this `unsafe` {}", kind), diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs index 1e57b03ced4..9eec7e0e8fe 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs @@ -13,6 +13,9 @@ unsafe fn deny_level() { //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block VOID = (); //~^ ERROR use of mutable static is unsafe and requires unsafe block + + unsafe {} + //~^ ERROR unnecessary `unsafe` block } // Check that `unsafe_op_in_unsafe_fn` works starting from the `warn` level. @@ -25,6 +28,8 @@ unsafe fn warning_level() { //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block VOID = (); //~^ ERROR use of mutable static is unsafe and requires unsafe block + unsafe {} + //~^ ERROR unnecessary `unsafe` block } unsafe fn explicit_block() { diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr index cc595df12cc..278a036c9f1 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr @@ -27,43 +27,11 @@ LL | VOID = (); | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior -error: call to unsafe function is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:22:5 - | -LL | unsf(); - | ^^^^^^ call to unsafe function - | -note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:20:8 - | -LL | #[deny(warnings)] - | ^^^^^^^^ - = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` - = note: consult the function's documentation for information on how to avoid undefined behavior - -error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:24:5 - | -LL | *PTR; - | ^^^^ dereference of raw pointer - | - = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior - -error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:5 - | -LL | VOID = (); - | ^^^^^^^^^ use of mutable static - | - = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior - error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:40:14 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5 | -LL | unsafe { unsafe { unsf() } } - | ------ ^^^^^^ unnecessary `unsafe` block - | | - | because it's nested under this `unsafe` block +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:3:9 @@ -71,20 +39,70 @@ note: the lint level is defined here LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ -error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:51:5 +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:5 | +LL | unsf(); + | ^^^^^^ call to unsafe function + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:23:8 + | +LL | #[deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5 + | +LL | *PTR; + | ^^^^ dereference of raw pointer + | + = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: use of mutable static is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5 + | +LL | VOID = (); + | ^^^^^^^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:45:14 + | +LL | unsafe { unsafe { unsf() } } + | ------ ^^^^^^ unnecessary `unsafe` block + | | + | because it's nested under this `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:56:5 + | +LL | unsafe fn allow_level() { + | ----------------------- because it's nested under this `unsafe` fn +... LL | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:63:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:68:9 | +LL | unsafe fn nested_allow_level() { + | ------------------------------ because it's nested under this `unsafe` fn +... LL | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block error[E0133]: call to unsafe function is unsafe and requires unsafe block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:69:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:74:5 | LL | unsf(); | ^^^^^^ call to unsafe function @@ -92,13 +110,13 @@ LL | unsf(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:73:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:9 | LL | unsf(); | ^^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior -error: aborting due to 11 previous errors +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0133`.