From 2136a5cfad69337222b5b02f934825e5d346f9ca Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sun, 17 Jan 2021 11:07:43 +0100 Subject: [PATCH] Fix `unused_unsafe` label with `unsafe_block_in_unsafe_fn --- .../rustc_mir/src/transform/check_unsafety.rs | 17 ++++--- .../unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs | 5 ++ .../rfc-2585-unsafe_op_in_unsafe_fn.stderr | 50 +++++++++++++------ 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index e64955c4986ce..4f177d4ef0248 100644 --- a/compiler/rustc_mir/src/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs @@ -580,24 +580,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 @@ -610,7 +609,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 1e57b03ced48b..9eec7e0e8fe62 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 cc595df12cc44..278a036c9f19f 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,14 +27,26 @@ LL | VOID = (); | = 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:17:5 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:3:9 + | +LL | #![deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + error: call to unsafe function is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:22:5 + --> $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:20:8 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:23:8 | LL | #[deny(warnings)] | ^^^^^^^^ @@ -42,7 +54,7 @@ LL | #[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 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -50,7 +62,7 @@ LL | *PTR; = 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 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5 | LL | VOID = (); | ^^^^^^^^^ use of mutable static @@ -58,33 +70,39 @@ LL | VOID = (); = 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: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 - | -note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:3:9 - | -LL | #![deny(unused_unsafe)] - | ^^^^^^^^^^^^^ error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:51:5 + --> $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`.