Skip to content

Commit 370bf15

Browse files
authored
Rollup merge of rust-lang#97962 - eholk:drop-tracking-must-not-suspend, r=cjgillot
Make must_not_suspend lint see through references when drop tracking is enabled See rust-lang#97333. With drop tracking enabled, sometimes values that were previously linted are now considered dropped and not linted. This change makes must_not_suspend traverse through references to still catch these values. Unfortunately, this leads to duplicate warnings in some cases (e.g. [dedup.rs](https://cs.github.com/rust-lang/rust/blob/9a74608543d499bcc7dd505e195e8bfab9447315/src/test/ui/lint/must_not_suspend/dedup.rs#L4)), so we only use the new behavior when drop tracking is enabled. cc ``@guswynn``
2 parents 9c20b2a + 0da8199 commit 370bf15

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

compiler/rustc_typeck/src/check/generator_interior.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
457457
}
458458

459459
#[derive(Default)]
460-
pub struct SuspendCheckData<'a, 'tcx> {
460+
struct SuspendCheckData<'a, 'tcx> {
461461
expr: Option<&'tcx Expr<'tcx>>,
462462
source_span: Span,
463463
yield_span: Span,
@@ -472,7 +472,7 @@ pub struct SuspendCheckData<'a, 'tcx> {
472472
//
473473
// Note that this technique was chosen over things like a `Suspend` marker trait
474474
// as it is simpler and has precedent in the compiler
475-
pub fn check_must_not_suspend_ty<'tcx>(
475+
fn check_must_not_suspend_ty<'tcx>(
476476
fcx: &FnCtxt<'_, 'tcx>,
477477
ty: Ty<'tcx>,
478478
hir_id: HirId,
@@ -489,6 +489,8 @@ pub fn check_must_not_suspend_ty<'tcx>(
489489

490490
let plural_suffix = pluralize!(data.plural_len);
491491

492+
debug!("Checking must_not_suspend for {}", ty);
493+
492494
match *ty.kind() {
493495
ty::Adt(..) if ty.is_box() => {
494496
let boxed_ty = ty.boxed_ty();
@@ -580,6 +582,12 @@ pub fn check_must_not_suspend_ty<'tcx>(
580582
},
581583
)
582584
}
585+
// If drop tracking is enabled, we want to look through references, since the referrent
586+
// may not be considered live across the await point.
587+
ty::Ref(_region, ty, _mutability) if fcx.sess().opts.unstable_opts.drop_tracking => {
588+
let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix);
589+
check_must_not_suspend_ty(fcx, ty, hir_id, SuspendCheckData { descr_pre, ..data })
590+
}
583591
_ => false,
584592
}
585593
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// edition:2018
2+
// compile-flags: -Zdrop-tracking
3+
#![feature(must_not_suspend)]
4+
#![deny(must_not_suspend)]
5+
6+
#[must_not_suspend = "You gotta use Umm's, ya know?"]
7+
struct Umm {
8+
i: i64
9+
}
10+
11+
struct Bar {
12+
u: Umm,
13+
}
14+
15+
async fn other() {}
16+
17+
impl Bar {
18+
async fn uhoh(&mut self) {
19+
let guard = &mut self.u; //~ ERROR `Umm` held across
20+
21+
other().await;
22+
23+
*guard = Umm {
24+
i: 2
25+
}
26+
}
27+
}
28+
29+
fn main() {
30+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error: reference to `Umm` held across a suspend point, but should not be
2+
--> $DIR/ref-drop-tracking.rs:19:13
3+
|
4+
LL | let guard = &mut self.u;
5+
| ^^^^^
6+
LL |
7+
LL | other().await;
8+
| ------ the value is held across this suspend point
9+
|
10+
note: the lint level is defined here
11+
--> $DIR/ref-drop-tracking.rs:4:9
12+
|
13+
LL | #![deny(must_not_suspend)]
14+
| ^^^^^^^^^^^^^^^^
15+
note: You gotta use Umm's, ya know?
16+
--> $DIR/ref-drop-tracking.rs:19:13
17+
|
18+
LL | let guard = &mut self.u;
19+
| ^^^^^
20+
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
21+
--> $DIR/ref-drop-tracking.rs:19:13
22+
|
23+
LL | let guard = &mut self.u;
24+
| ^^^^^
25+
26+
error: aborting due to previous error
27+

0 commit comments

Comments
 (0)