Skip to content

Commit e319670

Browse files
authored
Rollup merge of rust-lang#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 rust-lang#85421, but the issue predates that PR.
2 parents 45faa10 + b07bb6d commit e319670

File tree

9 files changed

+43
-25
lines changed

9 files changed

+43
-25
lines changed

compiler/rustc_middle/src/mir/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ impl<'tcx> Body<'tcx> {
494494
#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
495495
pub enum Safety {
496496
Safe,
497+
/// Unsafe because of compiler-generated unsafe code, like `await` desugaring
498+
BuiltinUnsafe,
497499
/// Unsafe because of an unsafe fn
498500
FnUnsafe,
499501
/// Unsafe because of an `unsafe` block

compiler/rustc_middle/src/thir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ pub struct Adt<'tcx> {
114114
#[derive(Copy, Clone, Debug, HashStable)]
115115
pub enum BlockSafety {
116116
Safe,
117+
BuiltinUnsafe,
117118
ExplicitUnsafe(hir::HirId),
118119
}
119120

compiler/rustc_mir/src/transform/check_unsafety.rs

+1
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
321321
}
322322
false
323323
}
324+
Safety::BuiltinUnsafe => true,
324325
Safety::ExplicitUnsafe(hir_id) => {
325326
// mark unsafe block as used if there are any unsafe operations inside
326327
if !violations.is_empty() {

compiler/rustc_mir_build/src/build/block.rs

+1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
214214
debug!("update_source_scope_for({:?}, {:?})", span, safety_mode);
215215
let new_unsafety = match safety_mode {
216216
BlockSafety::Safe => None,
217+
BlockSafety::BuiltinUnsafe => Some(Safety::BuiltinUnsafe),
217218
BlockSafety::ExplicitUnsafe(hir_id) => {
218219
match self.in_scope_unsafe {
219220
Safety::Safe => {}

compiler/rustc_mir_build/src/check_unsafety.rs

+20-13
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
2929
}
3030

3131
impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
32-
fn in_safety_context<R>(
33-
&mut self,
34-
safety_context: SafetyContext,
35-
f: impl FnOnce(&mut Self) -> R,
36-
) {
32+
fn in_safety_context(&mut self, safety_context: SafetyContext, f: impl FnOnce(&mut Self)) {
3733
if let (
3834
SafetyContext::UnsafeBlock { span: enclosing_span, .. },
3935
SafetyContext::UnsafeBlock { span: block_span, hir_id, .. },
@@ -63,14 +59,14 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
6359
);
6460
}
6561
self.safety_context = prev_context;
66-
return;
6762
}
6863
}
6964

7065
fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) {
7166
let (description, note) = kind.description_and_note();
7267
let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
7368
match self.safety_context {
69+
SafetyContext::BuiltinUnsafeBlock => {}
7470
SafetyContext::UnsafeBlock { ref mut used, .. } => {
7571
if !self.body_unsafety.is_unsafe() || !unsafe_op_in_unsafe_fn_allowed {
7672
// Mark this block as useful
@@ -142,13 +138,23 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
142138
}
143139

144140
fn visit_block(&mut self, block: &Block) {
145-
if let BlockSafety::ExplicitUnsafe(hir_id) = block.safety_mode {
146-
self.in_safety_context(
147-
SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false },
148-
|this| visit::walk_block(this, block),
149-
);
150-
} else {
151-
visit::walk_block(self, block);
141+
match block.safety_mode {
142+
// compiler-generated unsafe code should not count towards the usefulness of
143+
// an outer unsafe block
144+
BlockSafety::BuiltinUnsafe => {
145+
self.in_safety_context(SafetyContext::BuiltinUnsafeBlock, |this| {
146+
visit::walk_block(this, block)
147+
});
148+
}
149+
BlockSafety::ExplicitUnsafe(hir_id) => {
150+
self.in_safety_context(
151+
SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false },
152+
|this| visit::walk_block(this, block),
153+
);
154+
}
155+
BlockSafety::Safe => {
156+
visit::walk_block(self, block);
157+
}
152158
}
153159
}
154160

@@ -250,6 +256,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
250256
#[derive(Clone, Copy)]
251257
enum SafetyContext {
252258
Safe,
259+
BuiltinUnsafeBlock,
253260
UnsafeFn,
254261
UnsafeBlock { span: Span, hir_id: hir::HirId, used: bool },
255262
}

compiler/rustc_mir_build/src/thir/cx/block.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ impl<'tcx> Cx<'tcx> {
2626
expr: block.expr.map(|expr| self.mirror_expr(expr)),
2727
safety_mode: match block.rules {
2828
hir::BlockCheckMode::DefaultBlock => BlockSafety::Safe,
29-
hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(block.hir_id),
29+
hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated) => {
30+
BlockSafety::BuiltinUnsafe
31+
}
32+
hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) => {
33+
BlockSafety::ExplicitUnsafe(block.hir_id)
34+
}
3035
},
3136
}
3237
}

src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.mir.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: unnecessary `unsafe` block
2-
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:5
2+
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:9
33
|
4-
LL | unsafe { println!("foo"); }
5-
| ^^^^^^ unnecessary `unsafe` block
4+
LL | unsafe { async {}.await; }
5+
| ^^^^^^ unnecessary `unsafe` block
66
|
77
note: the lint level is defined here
8-
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:6:9
8+
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:5:9
99
|
1010
LL | #![deny(unused_unsafe)]
1111
| ^^^^^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
// issue #12418
2-
1+
// edition:2018
32
// revisions: mir thir
43
// [thir]compile-flags: -Z thir-unsafeck
54

65
#![deny(unused_unsafe)]
76

87
fn main() {
9-
unsafe { println!("foo"); } //~ ERROR unnecessary `unsafe`
8+
let _ = async {
9+
unsafe { async {}.await; } //~ ERROR unnecessary `unsafe`
10+
};
1011
}

src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.thir.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: unnecessary `unsafe` block
2-
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:5
2+
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:9
33
|
4-
LL | unsafe { println!("foo"); }
5-
| ^^^^^^ unnecessary `unsafe` block
4+
LL | unsafe { async {}.await; }
5+
| ^^^^^^ unnecessary `unsafe` block
66
|
77
note: the lint level is defined here
8-
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:6:9
8+
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:5:9
99
|
1010
LL | #![deny(unused_unsafe)]
1111
| ^^^^^^^^^^^^^

0 commit comments

Comments
 (0)