about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-06-22 20:01:05 +0900
committerGitHub <noreply@github.com>2021-06-22 20:01:05 +0900
commit8ec4e7dfdd5b90aa8867bf07e4d68f57908b080e (patch)
tree5e8e26643667d41959435fd8212835c4c33ba366 /compiler
parent8af9339e49304f504d6c1c6c2210c44bbed45fc4 (diff)
parentb07bb6d698d842f05b1664b8824671080274d53d (diff)
downloadrust-8ec4e7dfdd5b90aa8867bf07e4d68f57908b080e.tar.gz
rust-8ec4e7dfdd5b90aa8867bf07e4d68f57908b080e.zip
Rollup merge of #86517 - camsteffen:unused-unsafe-async, r=LeSeulArtichaut
Fix `unused_unsafe` around `await`

Enables `unused_unsafe` lint for `unsafe { future.await }`.

The existing test for this is `unsafe { println!() }`, so I assume that `println!` used to contain compiler-generated unsafe but this is no longer true, and so the existing test is broken. I replaced the test with `unsafe { ...await }`. I believe `await` is currently the only instance of compiler-generated unsafe.

Reverts some parts of #85421, but the issue predates that PR.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/thir.rs1
-rw-r--r--compiler/rustc_mir/src/transform/check_unsafety.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/block.rs1
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs33
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/block.rs7
6 files changed, 31 insertions, 14 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 0daaec272fd..672686410f9 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -494,6 +494,8 @@ impl<'tcx> Body<'tcx> {
 #[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
 pub enum Safety {
     Safe,
+    /// Unsafe because of compiler-generated unsafe code, like `await` desugaring
+    BuiltinUnsafe,
     /// Unsafe because of an unsafe fn
     FnUnsafe,
     /// Unsafe because of an `unsafe` block
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 2f107e7b96c..6b2e542ee70 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -114,6 +114,7 @@ pub struct Adt<'tcx> {
 #[derive(Copy, Clone, Debug, HashStable)]
 pub enum BlockSafety {
     Safe,
+    BuiltinUnsafe,
     ExplicitUnsafe(hir::HirId),
 }
 
diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs
index 324a5257f5d..103ddda1a1d 100644
--- a/compiler/rustc_mir/src/transform/check_unsafety.rs
+++ b/compiler/rustc_mir/src/transform/check_unsafety.rs
@@ -321,6 +321,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                 }
                 false
             }
+            Safety::BuiltinUnsafe => true,
             Safety::ExplicitUnsafe(hir_id) => {
                 // mark unsafe block as used if there are any unsafe operations inside
                 if !violations.is_empty() {
diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs
index 4e1983aca94..df71379c1d8 100644
--- a/compiler/rustc_mir_build/src/build/block.rs
+++ b/compiler/rustc_mir_build/src/build/block.rs
@@ -214,6 +214,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         debug!("update_source_scope_for({:?}, {:?})", span, safety_mode);
         let new_unsafety = match safety_mode {
             BlockSafety::Safe => None,
+            BlockSafety::BuiltinUnsafe => Some(Safety::BuiltinUnsafe),
             BlockSafety::ExplicitUnsafe(hir_id) => {
                 match self.in_scope_unsafe {
                     Safety::Safe => {}
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index e4ed5dece86..4e80931ec03 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -29,11 +29,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
 }
 
 impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
-    fn in_safety_context<R>(
-        &mut self,
-        safety_context: SafetyContext,
-        f: impl FnOnce(&mut Self) -> R,
-    ) {
+    fn in_safety_context(&mut self, safety_context: SafetyContext, f: impl FnOnce(&mut Self)) {
         if let (
             SafetyContext::UnsafeBlock { span: enclosing_span, .. },
             SafetyContext::UnsafeBlock { span: block_span, hir_id, .. },
@@ -63,7 +59,6 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
                 );
             }
             self.safety_context = prev_context;
-            return;
         }
     }
 
@@ -71,6 +66,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
         let (description, note) = kind.description_and_note();
         let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
         match self.safety_context {
+            SafetyContext::BuiltinUnsafeBlock => {}
             SafetyContext::UnsafeBlock { ref mut used, .. } => {
                 if !self.body_unsafety.is_unsafe() || !unsafe_op_in_unsafe_fn_allowed {
                     // Mark this block as useful
@@ -142,13 +138,23 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
     }
 
     fn visit_block(&mut self, block: &Block) {
-        if let BlockSafety::ExplicitUnsafe(hir_id) = block.safety_mode {
-            self.in_safety_context(
-                SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false },
-                |this| visit::walk_block(this, block),
-            );
-        } else {
-            visit::walk_block(self, block);
+        match block.safety_mode {
+            // compiler-generated unsafe code should not count towards the usefulness of
+            // an outer unsafe block
+            BlockSafety::BuiltinUnsafe => {
+                self.in_safety_context(SafetyContext::BuiltinUnsafeBlock, |this| {
+                    visit::walk_block(this, block)
+                });
+            }
+            BlockSafety::ExplicitUnsafe(hir_id) => {
+                self.in_safety_context(
+                    SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false },
+                    |this| visit::walk_block(this, block),
+                );
+            }
+            BlockSafety::Safe => {
+                visit::walk_block(self, block);
+            }
         }
     }
 
@@ -250,6 +256,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
 #[derive(Clone, Copy)]
 enum SafetyContext {
     Safe,
+    BuiltinUnsafeBlock,
     UnsafeFn,
     UnsafeBlock { span: Span, hir_id: hir::HirId, used: bool },
 }
diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs
index 4fe8cd8541a..2d9b5c1d98a 100644
--- a/compiler/rustc_mir_build/src/thir/cx/block.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/block.rs
@@ -26,7 +26,12 @@ impl<'tcx> Cx<'tcx> {
             expr: block.expr.map(|expr| self.mirror_expr(expr)),
             safety_mode: match block.rules {
                 hir::BlockCheckMode::DefaultBlock => BlockSafety::Safe,
-                hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(block.hir_id),
+                hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated) => {
+                    BlockSafety::BuiltinUnsafe
+                }
+                hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) => {
+                    BlockSafety::ExplicitUnsafe(block.hir_id)
+                }
             },
         }
     }