Skip to content

Commit

Permalink
Rollup merge of rust-lang#122701 - compiler-errors:allocator-suspend,…
Browse files Browse the repository at this point in the history
… r=oli-obk

Detect allocator for box in `must_not_suspend` lint

I don't expect this to happen in practice, but better to check than not.

Fixes rust-lang#122643
  • Loading branch information
matthiaskrgr committed Mar 18, 2024
2 parents 1179590 + 0db06bf commit 010dc4a
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
14 changes: 10 additions & 4 deletions compiler/rustc_mir_transform/src/coroutine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1964,15 +1964,21 @@ fn check_must_not_suspend_ty<'tcx>(
debug!("Checking must_not_suspend for {}", ty);

match *ty.kind() {
ty::Adt(..) if ty.is_box() => {
let boxed_ty = ty.boxed_ty();
let descr_pre = &format!("{}boxed ", data.descr_pre);
ty::Adt(_, args) if ty.is_box() => {
let boxed_ty = args.type_at(0);
let allocator_ty = args.type_at(1);
check_must_not_suspend_ty(
tcx,
boxed_ty,
hir_id,
param_env,
SuspendCheckData { descr_pre, ..data },
SuspendCheckData { descr_pre: &format!("{}boxed ", data.descr_pre), ..data },
) || check_must_not_suspend_ty(
tcx,
allocator_ty,
hir_id,
param_env,
SuspendCheckData { descr_pre: &format!("{}allocator ", data.descr_pre), ..data },
)
}
ty::Adt(def, _) => check_must_not_suspend_def(tcx, def.did(), hir_id, data),
Expand Down
30 changes: 30 additions & 0 deletions tests/ui/lint/must_not_suspend/allocator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//@ edition: 2021

#![feature(must_not_suspend, allocator_api)]
#![deny(must_not_suspend)]

use std::alloc::*;
use std::ptr::NonNull;

#[must_not_suspend]
struct MyAllocatorWhichMustNotSuspend;

unsafe impl Allocator for MyAllocatorWhichMustNotSuspend {
fn allocate(&self, l: Layout) -> Result<NonNull<[u8]>, AllocError> {
Global.allocate(l)
}
unsafe fn deallocate(&self, p: NonNull<u8>, l: Layout) {
Global.deallocate(p, l)
}
}

async fn suspend() {}

async fn foo() {
let x = Box::new_in(1i32, MyAllocatorWhichMustNotSuspend);
//~^ ERROR allocator `MyAllocatorWhichMustNotSuspend` held across a suspend point, but should not be
suspend().await;
drop(x);
}

fn main() {}
22 changes: 22 additions & 0 deletions tests/ui/lint/must_not_suspend/allocator.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error: allocator `MyAllocatorWhichMustNotSuspend` held across a suspend point, but should not be
--> $DIR/allocator.rs:24:9
|
LL | let x = Box::new_in(1i32, MyAllocatorWhichMustNotSuspend);
| ^
LL |
LL | suspend().await;
| ----- the value is held across this suspend point
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
--> $DIR/allocator.rs:24:9
|
LL | let x = Box::new_in(1i32, MyAllocatorWhichMustNotSuspend);
| ^
note: the lint level is defined here
--> $DIR/allocator.rs:4:9
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

0 comments on commit 010dc4a

Please sign in to comment.