about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/span/lint-unused-unsafe-thir.rs61
-rw-r--r--src/test/ui/span/lint-unused-unsafe-thir.stderr (renamed from src/test/ui/span/lint-unused-unsafe.thir.stderr)18
-rw-r--r--src/test/ui/span/lint-unused-unsafe.mir.stderr1795
-rw-r--r--src/test/ui/span/lint-unused-unsafe.rs1049
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr20
5 files changed, 2907 insertions, 36 deletions
diff --git a/src/test/ui/span/lint-unused-unsafe-thir.rs b/src/test/ui/span/lint-unused-unsafe-thir.rs
new file mode 100644
index 00000000000..95a537ed282
--- /dev/null
+++ b/src/test/ui/span/lint-unused-unsafe-thir.rs
@@ -0,0 +1,61 @@
+// FIXME: This file is tracking old lint behavior that's still unchanged in the
+// unstable -Zthir-unsafeck implementation. See lint-unused-unsafe.rs for more details.
+//
+// Exercise the unused_unsafe attribute in some positive and negative cases
+
+// compile-flags: -Zthir-unsafeck
+
+#![allow(dead_code)]
+#![deny(unused_unsafe)]
+
+
+mod foo {
+    extern "C" {
+        pub fn bar();
+    }
+}
+
+fn callback<T, F>(_f: F) -> T where F: FnOnce() -> T { panic!() }
+unsafe fn unsf() {}
+
+fn bad1() { unsafe {} }                  //~ ERROR: unnecessary `unsafe` block
+fn bad2() { unsafe { bad1() } }          //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad3() { unsafe {} }           //~ ERROR: unnecessary `unsafe` block
+fn bad4() { unsafe { callback(||{}) } }  //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad5() { unsafe { unsf() } }   //~ ERROR: unnecessary `unsafe` block
+fn bad6() {
+    unsafe {                             // don't put the warning here
+        unsafe {                         //~ ERROR: unnecessary `unsafe` block
+            unsf()
+        }
+    }
+}
+unsafe fn bad7() {
+    unsafe {                             //~ ERROR: unnecessary `unsafe` block
+        unsafe {                         //~ ERROR: unnecessary `unsafe` block
+            unsf()
+        }
+    }
+}
+
+unsafe fn good0() { unsf() }
+fn good1() { unsafe { unsf() } }
+fn good2() {
+    /* bug uncovered when implementing warning about unused unsafe blocks. Be
+       sure that when purity is inherited that the source of the unsafe-ness
+       is tracked correctly */
+    unsafe {
+        unsafe fn what() -> Vec<String> { panic!() }
+
+        callback(|| {
+            what();
+        });
+    }
+}
+
+unsafe fn good3() { foo::bar() }
+fn good4() { unsafe { foo::bar() } }
+
+#[allow(unused_unsafe)] fn allowed() { unsafe {} }
+
+fn main() {}
diff --git a/src/test/ui/span/lint-unused-unsafe.thir.stderr b/src/test/ui/span/lint-unused-unsafe-thir.stderr
index dda45c3679a..6654910c5cd 100644
--- a/src/test/ui/span/lint-unused-unsafe.thir.stderr
+++ b/src/test/ui/span/lint-unused-unsafe-thir.stderr
@@ -1,23 +1,23 @@
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:19:13
+  --> $DIR/lint-unused-unsafe-thir.rs:21:13
    |
 LL | fn bad1() { unsafe {} }
    |             ^^^^^^ unnecessary `unsafe` block
    |
 note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:7:9
+  --> $DIR/lint-unused-unsafe-thir.rs:9:9
    |
 LL | #![deny(unused_unsafe)]
    |         ^^^^^^^^^^^^^
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:20:13
+  --> $DIR/lint-unused-unsafe-thir.rs:22:13
    |
 LL | fn bad2() { unsafe { bad1() } }
    |             ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:21:20
+  --> $DIR/lint-unused-unsafe-thir.rs:23:20
    |
 LL | unsafe fn bad3() { unsafe {} }
    | ----------------   ^^^^^^ unnecessary `unsafe` block
@@ -25,13 +25,13 @@ LL | unsafe fn bad3() { unsafe {} }
    | because it's nested under this `unsafe` fn
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:22:13
+  --> $DIR/lint-unused-unsafe-thir.rs:24:13
    |
 LL | fn bad4() { unsafe { callback(||{}) } }
    |             ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:23:20
+  --> $DIR/lint-unused-unsafe-thir.rs:25:20
    |
 LL | unsafe fn bad5() { unsafe { unsf() } }
    | ----------------   ^^^^^^ unnecessary `unsafe` block
@@ -39,7 +39,7 @@ LL | unsafe fn bad5() { unsafe { unsf() } }
    | because it's nested under this `unsafe` fn
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:26:9
+  --> $DIR/lint-unused-unsafe-thir.rs:28:9
    |
 LL |     unsafe {                             // don't put the warning here
    |     ------ because it's nested under this `unsafe` block
@@ -47,7 +47,7 @@ LL |         unsafe {
    |         ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:33:9
+  --> $DIR/lint-unused-unsafe-thir.rs:35:9
    |
 LL |     unsafe {
    |     ------ because it's nested under this `unsafe` block
@@ -55,7 +55,7 @@ LL |         unsafe {
    |         ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:32:5
+  --> $DIR/lint-unused-unsafe-thir.rs:34:5
    |
 LL | unsafe fn bad7() {
    | ---------------- because it's nested under this `unsafe` fn
diff --git a/src/test/ui/span/lint-unused-unsafe.mir.stderr b/src/test/ui/span/lint-unused-unsafe.mir.stderr
index c2adb7be7a2..850550a1d8f 100644
--- a/src/test/ui/span/lint-unused-unsafe.mir.stderr
+++ b/src/test/ui/span/lint-unused-unsafe.mir.stderr
@@ -1,67 +1,1824 @@
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:19:13
+  --> $DIR/lint-unused-unsafe.rs:26:13
    |
 LL | fn bad1() { unsafe {} }
    |             ^^^^^^ unnecessary `unsafe` block
    |
 note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:7:9
+  --> $DIR/lint-unused-unsafe.rs:14:9
    |
 LL | #![deny(unused_unsafe)]
    |         ^^^^^^^^^^^^^
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:20:13
+  --> $DIR/lint-unused-unsafe.rs:27:13
    |
 LL | fn bad2() { unsafe { bad1() } }
    |             ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:21:20
+  --> $DIR/lint-unused-unsafe.rs:28:20
    |
 LL | unsafe fn bad3() { unsafe {} }
-   | ----------------   ^^^^^^ unnecessary `unsafe` block
-   | |
-   | because it's nested under this `unsafe` fn
+   |                    ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:22:13
+  --> $DIR/lint-unused-unsafe.rs:29:13
    |
 LL | fn bad4() { unsafe { callback(||{}) } }
    |             ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:23:20
+  --> $DIR/lint-unused-unsafe.rs:30:20
    |
 LL | unsafe fn bad5() { unsafe { unsf() } }
    | ----------------   ^^^^^^ unnecessary `unsafe` block
    | |
    | because it's nested under this `unsafe` fn
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+   = note: `#[allow(unsafe_op_in_unsafe_fn)]` on by default
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:26:9
+  --> $DIR/lint-unused-unsafe.rs:32:5
    |
-LL |     unsafe {                             // don't put the warning here
-   |     ------ because it's nested under this `unsafe` block
-LL |         unsafe {
-   |         ^^^^^^ unnecessary `unsafe` block
+LL |     unsafe {
+   |     ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:32:5
+  --> $DIR/lint-unused-unsafe.rs:39:5
    |
-LL | unsafe fn bad7() {
-   | ---------------- because it's nested under this `unsafe` fn
 LL |     unsafe {
    |     ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:33:9
+  --> $DIR/lint-unused-unsafe.rs:40:9
    |
 LL | unsafe fn bad7() {
    | ---------------- because it's nested under this `unsafe` fn
 LL |     unsafe {
 LL |         unsafe {
    |         ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:74:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:83:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:84:13
+   |
+LL |             unsafe {}
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:85:13
+   |
+LL |             unsafe {}
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:90:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:100:13
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+LL |             unsf();
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:101:13
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:102:13
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:112:17
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe { unsf() }
+   |                 ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:110:20
+   |
+LL |             #[deny(unused_unsafe)]
+   |                    ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:113:17
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe { unsf() }
+   |                 ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:114:17
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe { unsf() }
+   |                 ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:124:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:134:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:135:13
+   |
+LL |             unsafe {}
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:136:13
+   |
+LL |             unsafe {}
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:142:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:153:13
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+LL |             unsf();
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:154:13
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:155:13
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:166:17
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe { unsf() }
+   |                 ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:164:20
+   |
+LL |             #[deny(unused_unsafe)]
+   |                    ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:167:17
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe { unsf() }
+   |                 ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:168:17
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe { unsf() }
+   |                 ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:178:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:188:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:189:13
+   |
+LL |             unsafe {}
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:190:13
+   |
+LL |             unsafe {}
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:196:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:197:13
+   |
+LL |     unsafe fn granularity_2() {
+   |     ------------------------- because it's nested under this `unsafe` fn
+LL |         unsafe {
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:194:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:198:13
+   |
+LL |     unsafe fn granularity_2() {
+   |     ------------------------- because it's nested under this `unsafe` fn
+...
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:199:13
+   |
+LL |     unsafe fn granularity_2() {
+   |     ------------------------- because it's nested under this `unsafe` fn
+...
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:205:9
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:203:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:207:13
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:208:13
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:209:13
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |             unsafe { unsf() }
+   |             ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:220:17
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe { unsf() }
+   |                 ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:218:20
+   |
+LL |             #[deny(unused_unsafe)]
+   |                    ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:221:17
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe { unsf() }
+   |                 ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:222:17
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe { unsf() }
+   |                 ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:242:9
+   |
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:254:9
+   |
+LL |     unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+   |     ----------------------------------------------- because it's nested under this `unsafe` fn
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:252:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:268:13
+   |
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+LL |             unsafe {
+   |             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:286:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:295:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:296:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:297:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:302:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:312:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+LL |             unsf();
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:313:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:314:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:324:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:322:20
+   |
+LL |             #[deny(unused_unsafe)]
+   |                    ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:325:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:326:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:336:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:346:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:347:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:348:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:354:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:365:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+LL |             unsf();
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:366:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:367:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:378:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:376:20
+   |
+LL |             #[deny(unused_unsafe)]
+   |                    ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:379:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:380:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:390:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:400:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:401:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:402:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:408:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:409:24
+   |
+LL |     unsafe fn granularity_2() {
+   |     ------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:406:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:410:24
+   |
+LL |     unsafe fn granularity_2() {
+   |     ------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:411:24
+   |
+LL |     unsafe fn granularity_2() {
+   |     ------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:417:20
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:415:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:419:24
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:420:24
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:421:24
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { unsf() };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:432:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:430:20
+   |
+LL |             #[deny(unused_unsafe)]
+   |                    ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:433:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:434:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:454:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:466:20
+   |
+LL |     unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+   |     ----------------------------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:464:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:480:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:499:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:508:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:509:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:510:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:515:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:525:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+LL |             let _ = || unsf();
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:526:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:527:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:537:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { let _ = || unsf(); };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:535:20
+   |
+LL |             #[deny(unused_unsafe)]
+   |                    ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:538:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { let _ = || unsf(); };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:539:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { let _ = || unsf(); };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:549:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:559:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:560:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:561:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:567:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:578:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+LL |             let _ = || unsf();
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:579:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:580:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:591:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { let _ = || unsf(); };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:589:20
+   |
+LL |             #[deny(unused_unsafe)]
+   |                    ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:592:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { let _ = || unsf(); };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:593:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { let _ = || unsf(); };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:603:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:613:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:614:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:615:24
+   |
+LL |             let _ = || unsafe {};
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:621:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:622:24
+   |
+LL |     unsafe fn granularity_2() {
+   |     ------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:619:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:623:24
+   |
+LL |     unsafe fn granularity_2() {
+   |     ------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:624:24
+   |
+LL |     unsafe fn granularity_2() {
+   |     ------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:630:20
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:628:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:632:24
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:633:24
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:634:24
+   |
+LL |     unsafe fn top_level_used_2() {
+   |     ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |             let _ = || unsafe { let _ = || unsf(); };
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:645:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { let _ = || unsf(); };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:643:20
+   |
+LL |             #[deny(unused_unsafe)]
+   |                    ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:646:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { let _ = || unsf(); };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:647:28
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { let _ = || unsf(); };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:667:20
+   |
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:679:20
+   |
+LL |     unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+   |     ----------------------------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+   |                    ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:677:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:693:24
+   |
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:711:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:721:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:722:28
+   |
+LL |                 let _ = || unsafe {};
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:723:28
+   |
+LL |                 let _ = || unsafe {};
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:729:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:740:28
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+LL |                 unsf();
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:741:28
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:742:28
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:753:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:751:24
+   |
+LL |                 #[deny(unused_unsafe)]
+   |                        ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:754:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:755:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:765:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:775:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:776:28
+   |
+LL |                 let _ = || unsafe {};
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:777:28
+   |
+LL |                 let _ = || unsafe {};
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:783:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:784:28
+   |
+LL |         unsafe fn granularity_2() {
+   |         ------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:781:17
+   |
+LL |         #[allow(unsafe_op_in_unsafe_fn)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:785:28
+   |
+LL |         unsafe fn granularity_2() {
+   |         ------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:786:28
+   |
+LL |         unsafe fn granularity_2() {
+   |         ------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:792:24
+   |
+LL |         unsafe fn top_level_used_2() {
+   |         ---------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:790:17
+   |
+LL |         #[allow(unsafe_op_in_unsafe_fn)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:794:28
+   |
+LL |         unsafe fn top_level_used_2() {
+   |         ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:795:28
+   |
+LL |         unsafe fn top_level_used_2() {
+   |         ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:796:28
+   |
+LL |         unsafe fn top_level_used_2() {
+   |         ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:807:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:805:24
+   |
+LL |                 #[deny(unused_unsafe)]
+   |                        ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:808:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:809:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:829:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:841:24
+   |
+LL |         unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+   |         ----------------------------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:839:17
+   |
+LL |         #[allow(unsafe_op_in_unsafe_fn)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:855:28
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+LL |                 let _ = || unsafe {
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:869:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:879:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:880:28
+   |
+LL |                 let _ = || unsafe {};
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:881:28
+   |
+LL |                 let _ = || unsafe {};
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:887:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:898:28
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+LL |                 unsf();
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:899:28
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:900:28
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:911:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:909:24
+   |
+LL |                 #[deny(unused_unsafe)]
+   |                        ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:912:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:913:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:923:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:933:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:934:28
+   |
+LL |                 let _ = || unsafe {};
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:935:28
+   |
+LL |                 let _ = || unsafe {};
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:941:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:942:28
+   |
+LL |         unsafe fn granularity_2() {
+   |         ------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:939:17
+   |
+LL |         #[allow(unsafe_op_in_unsafe_fn)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:943:28
+   |
+LL |         unsafe fn granularity_2() {
+   |         ------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:944:28
+   |
+LL |         unsafe fn granularity_2() {
+   |         ------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:950:24
+   |
+LL |         unsafe fn top_level_used_2() {
+   |         ---------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:948:17
+   |
+LL |         #[allow(unsafe_op_in_unsafe_fn)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:952:28
+   |
+LL |         unsafe fn top_level_used_2() {
+   |         ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:953:28
+   |
+LL |         unsafe fn top_level_used_2() {
+   |         ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:954:28
+   |
+LL |         unsafe fn top_level_used_2() {
+   |         ---------------------------- because it's nested under this `unsafe` fn
+...
+LL |                 let _ = || unsafe { unsf() };
+   |                            ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:965:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:963:24
+   |
+LL |                 #[deny(unused_unsafe)]
+   |                        ^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:966:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:967:32
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+...
+LL |                     let _ = || unsafe { unsf() };
+   |                                ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:987:24
+   |
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:999:24
+   |
+LL |         unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+   |         ----------------------------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:997:17
+   |
+LL |         #[allow(unsafe_op_in_unsafe_fn)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1013:28
+   |
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+LL |                 let _ = || unsafe {
+   |                            ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1044:9
+   |
+LL |     unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() {
+   |     -------------------------------------------------- because it's nested under this `unsafe` fn
+LL |         unsafe {
+   |         ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:1045:21
+   |
+LL |             #[allow(unsafe_op_in_unsafe_fn)]
+   |                     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1059:29
+   |
+LL |             let _ = async { unsafe {
+   |                             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1066:33
+   |
+LL |             let _ = async { unsafe {
+   |                             ------ because it's nested under this `unsafe` block
+LL |                 let _ = async { unsf() };
+LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
+   |                                 ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1067:33
+   |
+LL |             let _ = async { unsafe {
+   |                             ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
+   |                                 ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1068:33
+   |
+LL |             let _ = async { unsafe {
+   |                             ------ because it's nested under this `unsafe` block
+...
+LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
+   |                                 ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1073:29
+   |
+LL |             let _ = async { unsafe {
+   |                             ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1074:33
+   |
+LL |     async unsafe fn async_blocks() {
+   |     ------------------------------ because it's nested under this `unsafe` fn
+...
+LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
+   |                                 ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/lint-unused-unsafe.rs:1071:17
+   |
+LL |         #[allow(unsafe_op_in_unsafe_fn)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1075:33
+   |
+LL |     async unsafe fn async_blocks() {
+   |     ------------------------------ because it's nested under this `unsafe` fn
+...
+LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
+   |                                 ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1076:33
+   |
+LL |     async unsafe fn async_blocks() {
+   |     ------------------------------ because it's nested under this `unsafe` fn
+...
+LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
+   |                                 ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1078:29
+   |
+LL |     async unsafe fn async_blocks() {
+   |     ------------------------------ because it's nested under this `unsafe` fn
+...
+LL |             let _ = async { unsafe {
+   |                             ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1080:33
+   |
+LL |     async unsafe fn async_blocks() {
+   |     ------------------------------ because it's nested under this `unsafe` fn
+...
+LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
+   |                                 ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1081:33
+   |
+LL |     async unsafe fn async_blocks() {
+   |     ------------------------------ because it's nested under this `unsafe` fn
+...
+LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
+   |                                 ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1082:33
+   |
+LL |     async unsafe fn async_blocks() {
+   |     ------------------------------ because it's nested under this `unsafe` fn
+...
+LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
+   |                                 ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1092:22
+   |
+LL |         let _x: [(); unsafe { 0 }] = [];
+   |                      ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/lint-unused-unsafe.rs:1096:22
+   |
+LL |         let _x: [(); unsafe { unsafe { size() } }] = [];
+   |                      ^^^^^^ unnecessary `unsafe` block
 
-error: aborting due to 8 previous errors
+error: aborting due to 201 previous errors
 
diff --git a/src/test/ui/span/lint-unused-unsafe.rs b/src/test/ui/span/lint-unused-unsafe.rs
index b889cc981ca..f8d1dff3572 100644
--- a/src/test/ui/span/lint-unused-unsafe.rs
+++ b/src/test/ui/span/lint-unused-unsafe.rs
@@ -1,7 +1,14 @@
 // Exercise the unused_unsafe attribute in some positive and negative cases
 
-// revisions: mir thir
-// [thir]compile-flags: -Zthir-unsafeck
+
+// edition:2018
+
+// revisions: mir
+
+// FIXME: Adapt -Zthir-unsafeck to behave the same as the mir version after #93678,
+// then delete lint-unused-unsafe-thir.rs, and go back to using the settings below
+// // revisions: mir thir
+// // [thir]compile-flags: -Zthir-unsafeck
 
 #![allow(dead_code)]
 #![deny(unused_unsafe)]
@@ -22,8 +29,8 @@ unsafe fn bad3() { unsafe {} }           //~ ERROR: unnecessary `unsafe` block
 fn bad4() { unsafe { callback(||{}) } }  //~ ERROR: unnecessary `unsafe` block
 unsafe fn bad5() { unsafe { unsf() } }   //~ ERROR: unnecessary `unsafe` block
 fn bad6() {
-    unsafe {                             // don't put the warning here
-        unsafe {                         //~ ERROR: unnecessary `unsafe` block
+    unsafe {                             //~ ERROR: unnecessary `unsafe` block
+        unsafe {                         // don't put the warning here
             unsf()
         }
     }
@@ -57,3 +64,1037 @@ fn good4() { unsafe { foo::bar() } }
 #[allow(unused_unsafe)] fn allowed() { unsafe {} }
 
 fn main() {}
+
+mod additional_tests {
+    unsafe fn unsf() {}
+
+    // some tests
+
+    fn inner_ignored() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unused_unsafe)]
+            unsafe {
+                unsf()
+            }
+        }
+    }
+
+    fn multi_level_unused() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsafe {} //~ ERROR: unnecessary `unsafe` block
+            unsafe {} //~ ERROR: unnecessary `unsafe` block
+        }
+    }
+
+    fn granularity() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() }
+            unsafe { unsf() }
+            unsafe { unsf() }
+        }
+    }
+
+    fn top_level_used() {
+        unsafe {
+            unsf();
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+        }
+
+    }
+
+    fn top_level_ignored() {
+        #[allow(unused_unsafe)]
+        unsafe {
+            #[deny(unused_unsafe)]
+            {
+                unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+                unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+                unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            }
+        }
+
+    }
+
+    // same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn inner_ignored_1() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unused_unsafe)]
+            unsafe {
+                unsf()
+            }
+        }
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn multi_level_unused_1() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsafe {} //~ ERROR: unnecessary `unsafe` block
+            unsafe {} //~ ERROR: unnecessary `unsafe` block
+        }
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn granularity_1() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() }
+            unsafe { unsf() }
+            unsafe { unsf() }
+        }
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_used_1() {
+        unsafe {
+            unsf();
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+        }
+
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_ignored_1() {
+        #[allow(unused_unsafe)]
+        unsafe {
+            #[deny(unused_unsafe)]
+            {
+                unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+                unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+                unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            }
+        }
+    }
+
+    // same tests, but unsafe_op_in_unsafe_fn allowed,
+    // so that *all* unsafe blocks are unused
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn inner_ignored_2() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unused_unsafe)]
+            unsafe {
+                unsf()
+            }
+        }
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn multi_level_unused_2() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsafe {} //~ ERROR: unnecessary `unsafe` block
+            unsafe {} //~ ERROR: unnecessary `unsafe` block
+        }
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granularity_2() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+        }
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_used_2() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsf();
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+        }
+
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_ignored_2() {
+        #[allow(unused_unsafe)]
+        unsafe {
+            #[deny(unused_unsafe)]
+            {
+                unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+                unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+                unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            }
+        }
+    }
+
+    // additional tests when using unsafe_op_in_unsafe_fn
+    // in more complex ways
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn() {
+        unsafe {
+            #[deny(unsafe_op_in_unsafe_fn)]
+            {
+                unsf();
+            }
+        }
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsafe {
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    unsf();
+                }
+            }
+        }
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsafe {
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    unsf();
+                }
+            }
+            unsf();
+        }
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+        unsafe {
+            unsafe { //~ ERROR: unnecessary `unsafe` block
+                unsf();
+            }
+            #[deny(unsafe_op_in_unsafe_fn)]
+            {
+                unsf();
+            }
+        }
+    }
+}
+
+// the same set of tests, with closures everywhere
+mod additional_tests_closures {
+    unsafe fn unsf() {}
+
+    // some tests
+
+    fn inner_ignored() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                unsf()
+            };
+        };
+    }
+
+    fn multi_level_unused() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+        };
+    }
+
+    fn granularity() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() };
+            let _ = || unsafe { unsf() };
+            let _ = || unsafe { unsf() };
+        };
+    }
+
+    fn top_level_used() {
+        let _ = || unsafe {
+            unsf();
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+        };
+
+    }
+
+    fn top_level_ignored() {
+        #[allow(unused_unsafe)]
+        let _ = || unsafe {
+            #[deny(unused_unsafe)]
+            {
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            }
+        };
+
+    }
+
+    // same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn inner_ignored_1() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                unsf()
+            };
+        };
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn multi_level_unused_1() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+        };
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn granularity_1() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() };
+            let _ = || unsafe { unsf() };
+            let _ = || unsafe { unsf() };
+        };
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_used_1() {
+        let _ = || unsafe {
+            unsf();
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+        };
+
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_ignored_1() {
+        #[allow(unused_unsafe)]
+        let _ = || unsafe {
+            #[deny(unused_unsafe)]
+            {
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            }
+        };
+    }
+
+    // same tests, but unsafe_op_in_unsafe_fn allowed,
+    // so that *all* unsafe blocks are unused
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn inner_ignored_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                unsf()
+            };
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn multi_level_unused_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granularity_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_used_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            unsf();
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+        };
+
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_ignored_2() {
+        #[allow(unused_unsafe)]
+        let _ = || unsafe {
+            #[deny(unused_unsafe)]
+            {
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            }
+        };
+    }
+
+    // additional tests when using unsafe_op_in_unsafe_fn
+    // in more complex ways
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn() {
+        let _ = || unsafe {
+            #[deny(unsafe_op_in_unsafe_fn)]
+            {
+                unsf();
+            }
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    unsf();
+                }
+            };
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    unsf();
+                }
+            };
+            unsf();
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+        let _ = || unsafe {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                unsf();
+            };
+            #[deny(unsafe_op_in_unsafe_fn)]
+            {
+                unsf();
+            }
+        };
+    }
+}
+
+// the same set of tests, with closures everywhere
+// and closures on the unsafe fn calls
+mod additional_tests_even_more_closures {
+    unsafe fn unsf() {}
+
+    // some tests
+
+    fn inner_ignored() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                let _ = || unsf();
+            };
+        };
+    }
+
+    fn multi_level_unused() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+        };
+    }
+
+    fn granularity() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); };
+            let _ = || unsafe { let _ = || unsf(); };
+            let _ = || unsafe { let _ = || unsf(); };
+        };
+    }
+
+    fn top_level_used() {
+        let _ = || unsafe {
+            let _ = || unsf();
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+        };
+
+    }
+
+    fn top_level_ignored() {
+        #[allow(unused_unsafe)]
+        let _ = || unsafe {
+            #[deny(unused_unsafe)]
+            {
+                let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            }
+        };
+
+    }
+
+    // same tests in unsafe fn without unsafe_op_in_unsafe_fn allowed
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn inner_ignored_1() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                let _ = || unsf();
+            };
+        };
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn multi_level_unused_1() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+        };
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn granularity_1() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); };
+            let _ = || unsafe { let _ = || unsf(); };
+            let _ = || unsafe { let _ = || unsf(); };
+        };
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_used_1() {
+        let _ = || unsafe {
+            let _ = || unsf();
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+        };
+
+    }
+
+    #[deny(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_ignored_1() {
+        #[allow(unused_unsafe)]
+        let _ = || unsafe {
+            #[deny(unused_unsafe)]
+            {
+                let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            }
+        };
+    }
+
+    // same tests, but unsafe_op_in_unsafe_fn allowed,
+    // so that *all* unsafe blocks are unused
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn inner_ignored_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                let _ = || unsf();
+            };
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn multi_level_unused_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granularity_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_used_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsf();
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+        };
+
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn top_level_ignored_2() {
+        #[allow(unused_unsafe)]
+        let _ = || unsafe {
+            #[deny(unused_unsafe)]
+            {
+                let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            }
+        };
+    }
+
+    // additional tests when using unsafe_op_in_unsafe_fn
+    // in more complex ways
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn() {
+        let _ = || unsafe {
+            #[deny(unsafe_op_in_unsafe_fn)]
+            {
+                let _ = || unsf();
+            }
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    let _ = || unsf();
+                }
+            };
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    let _ = || unsf();
+                }
+            };
+            let _ = || unsf();
+        };
+    }
+
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+        let _ = || unsafe {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsf();
+            };
+            #[deny(unsafe_op_in_unsafe_fn)]
+            {
+                let _ = || unsf();
+            }
+        };
+    }
+}
+
+mod item_likes {
+    unsafe fn unsf() {}
+
+    struct S;
+    impl S {
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn inner_ignored_1() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                #[allow(unused_unsafe)]
+                let _ = || unsafe {
+                    unsf()
+                };
+            };
+        }
+
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn multi_level_unused_1() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            };
+        }
+
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn granularity_1() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() };
+                let _ = || unsafe { unsf() };
+                let _ = || unsafe { unsf() };
+            };
+        }
+
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn top_level_used_1() {
+            let _ = || unsafe {
+                unsf();
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            };
+
+        }
+
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn top_level_ignored_1() {
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                #[deny(unused_unsafe)]
+                {
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                }
+            };
+        }
+
+        // same tests, but unsafe_op_in_unsafe_fn allowed,
+        // so that *all* unsafe blocks are unused
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn inner_ignored_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                #[allow(unused_unsafe)]
+                let _ = || unsafe {
+                    unsf()
+                };
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn multi_level_unused_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granularity_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn top_level_used_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                unsf();
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            };
+
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn top_level_ignored_2() {
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                #[deny(unused_unsafe)]
+                {
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                }
+            };
+        }
+
+        // additional tests when using unsafe_op_in_unsafe_fn
+        // in more complex ways
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granular_disallow_op_in_unsafe_fn() {
+            let _ = || unsafe {
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    unsf();
+                }
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {
+                    #[deny(unsafe_op_in_unsafe_fn)]
+                    {
+                        unsf();
+                    }
+                };
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {
+                    #[deny(unsafe_op_in_unsafe_fn)]
+                    {
+                        unsf();
+                    }
+                };
+                unsf();
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+            let _ = || unsafe {
+                let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                    unsf();
+                };
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    unsf();
+                }
+            };
+        }
+    }
+
+    trait T {
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn inner_ignored_1() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                #[allow(unused_unsafe)]
+                let _ = || unsafe {
+                    unsf()
+                };
+            };
+        }
+
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn multi_level_unused_1() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            };
+        }
+
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn granularity_1() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() };
+                let _ = || unsafe { unsf() };
+                let _ = || unsafe { unsf() };
+            };
+        }
+
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn top_level_used_1() {
+            let _ = || unsafe {
+                unsf();
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            };
+
+        }
+
+        #[deny(unsafe_op_in_unsafe_fn)]
+        unsafe fn top_level_ignored_1() {
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                #[deny(unused_unsafe)]
+                {
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                }
+            };
+        }
+
+        // same tests, but unsafe_op_in_unsafe_fn allowed,
+        // so that *all* unsafe blocks are unused
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn inner_ignored_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                #[allow(unused_unsafe)]
+                let _ = || unsafe {
+                    unsf()
+                };
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn multi_level_unused_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {}; //~ ERROR: unnecessary `unsafe` block
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granularity_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn top_level_used_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                unsf();
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            };
+
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn top_level_ignored_2() {
+            #[allow(unused_unsafe)]
+            let _ = || unsafe {
+                #[deny(unused_unsafe)]
+                {
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                    let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                }
+            };
+        }
+
+        // additional tests when using unsafe_op_in_unsafe_fn
+        // in more complex ways
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granular_disallow_op_in_unsafe_fn() {
+            let _ = || unsafe {
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    unsf();
+                }
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granular_disallow_op_in_unsafe_fn_2() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {
+                    #[deny(unsafe_op_in_unsafe_fn)]
+                    {
+                        unsf();
+                    }
+                };
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granular_disallow_op_in_unsafe_fn_3() {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe {
+                    #[deny(unsafe_op_in_unsafe_fn)]
+                    {
+                        unsf();
+                    }
+                };
+                unsf();
+            };
+        }
+
+        #[allow(unsafe_op_in_unsafe_fn)]
+        unsafe fn granular_disallow_op_in_unsafe_fn_4() {
+            let _ = || unsafe {
+                let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+                    unsf();
+                };
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    unsf();
+                }
+            };
+        }
+    }
+}
+
+mod additional_tests_extra {
+    unsafe fn unsf() {}
+
+    // multiple uses with different `unsafe_op_in_unsafe_fn` in the same closure
+    #[allow(unsafe_op_in_unsafe_fn)]
+    unsafe fn granular_disallow_op_in_unsafe_fn() {
+        let _ = || unsafe {
+            let _ = || {
+                unsf();
+                #[deny(unsafe_op_in_unsafe_fn)]
+                {
+                    unsf();
+                }
+            };
+        };
+    }
+
+    #[warn(unsafe_op_in_unsafe_fn)]
+    unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() {
+        unsafe { //~ ERROR: unnecessary `unsafe` block
+            #[allow(unsafe_op_in_unsafe_fn)]
+            {
+                unsf();
+            }
+            #[allow(unsafe_op_in_unsafe_fn)]
+            {
+                unsf();
+            }
+        }
+    }
+
+    async unsafe fn async_blocks() {
+        #[deny(unsafe_op_in_unsafe_fn)]
+        {
+            let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsafe { let _ = async { unsf() }; }};
+                let _ = async { unsafe { let _ = async { unsf() }; }};
+                let _ = async { unsafe { let _ = async { unsf() }; }};
+            }};
+            let _ = async { unsafe {
+                let _ = async { unsf() };
+                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+            }};
+        }
+        #[allow(unsafe_op_in_unsafe_fn)]
+        {
+            let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+            }};
+            let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsf() };
+                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+            }};
+        }
+    }
+
+    fn used_unsafe_in_const() {
+        let _x: [(); unsafe { size() }] = [];
+    }
+
+    fn unused_unsafe_in_const_1() {
+        let _x: [(); unsafe { 0 }] = []; //~ ERROR: unnecessary `unsafe` block
+    }
+
+    fn unused_unsafe_in_const_2() {
+        let _x: [(); unsafe { unsafe { size() } }] = []; //~ ERROR: unnecessary `unsafe` block
+    }
+
+    const unsafe fn size() -> usize { 0 }
+}
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
index 9a522fac65f..163c101772c 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
@@ -76,12 +76,10 @@ LL |     unsafe {}
    |     ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:5
    |
 LL |     unsafe { unsafe { unsf() } }
-   |     ------   ^^^^^^ unnecessary `unsafe` block
-   |     |
-   |     because it's nested under this `unsafe` block
+   |     ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5
@@ -91,6 +89,13 @@ LL | unsafe fn allow_level() {
 ...
 LL |     unsafe { unsf() }
    |     ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:51:9
+   |
+LL | #[allow(unsafe_op_in_unsafe_fn)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: unnecessary `unsafe` block
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9
@@ -100,6 +105,13 @@ LL | unsafe fn nested_allow_level() {
 ...
 LL |         unsafe { unsf() }
    |         ^^^^^^ unnecessary `unsafe` block
+   |
+   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
+note: the lint level is defined here
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:63:13
+   |
+LL |     #[allow(unsafe_op_in_unsafe_fn)]
+   |             ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0133]: call to unsafe function is unsafe and requires unsafe block
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5