Detect allocator for box in must_not_suspend lint
This commit is contained in:
parent
3cdcdaf31b
commit
0db06bf004
@ -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),
|
||||
|
30
tests/ui/lint/must_not_suspend/allocator.rs
Normal file
30
tests/ui/lint/must_not_suspend/allocator.rs
Normal file
@ -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
tests/ui/lint/must_not_suspend/allocator.stderr
Normal file
22
tests/ui/lint/must_not_suspend/allocator.stderr
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user