Clippy lints / Suspicious
Clippy lint · Suspicious · checked with Clippy 0.1.99
clippy::await_holding_refcell_ref: Checks for calls to await while holding a RefCell, Ref, or RefMut
What it meansChecks for calls to await while holding a RefCell, Ref, or RefMut. It is in the suspicious group and warns by default.
Does it matter?
RefCell refs only check for exclusive mutable access at runtime. Holding a RefCell ref across an await suspension point risks panics from a mutable ref shared while other refs are outstanding.
Code that is most likely wrong or useless. Warns by default.
How to fix it
Clippy does not fix this one automatically. Change the code by hand:
Flagged
async fn foo(x: &RefCell<u32>) {
let mut y = x.borrow_mut();
*y += 1;
baz().await;
}
async fn bar(x: &RefCell<u32>) {
let mut y = x.borrow_mut();
*y += 1;
drop(y); // explicit drop
baz().await;
}
Write this instead
async fn foo(x: &RefCell<u32>) {
{
let mut y = x.borrow_mut();
*y += 1;
}
baz().await;
}
async fn bar(x: &RefCell<u32>) {
{
let mut y = x.borrow_mut();
*y += 1;
} // y dropped here at end of scope
baz().await;
}
Turn it off, or on
Allow it where it does not fit your code, as narrowly as you can:
On one item
#[allow(clippy::await_holding_refcell_ref)]
fn my_function() { /* ... */ }Whole crate (Cargo.toml)
[lints.clippy]
await_holding_refcell_ref = "allow"One run
cargo clippy -- -A clippy::await-holding-refcell-refThe [lints] table needs Rust 1.74 or newer. In a workspace, put it under [workspace.lints.clippy] and add [lints] workspace = true to each member.
Clippy's own documentation
What it does
Checks for calls to await while holding a RefCell, Ref, or RefMut.
Why is this bad?
RefCell refs only check for exclusive mutable access
at runtime. Holding a RefCell ref across an await suspension point
risks panics from a mutable ref shared while other refs are outstanding.
Known problems
Will report false positive for explicitly dropped refs
(#6353). A workaround for this is
to wrap the .borrow[_mut]() call in a block instead of explicitly dropping the ref.
Example
async fn foo(x: &RefCell<u32>) {
let mut y = x.borrow_mut();
*y += 1;
baz().await;
}
async fn bar(x: &RefCell<u32>) {
let mut y = x.borrow_mut();
*y += 1;
drop(y); // explicit drop
baz().await;
}
Use instead:
async fn foo(x: &RefCell<u32>) {
{
let mut y = x.borrow_mut();
*y += 1;
}
baz().await;
}
async fn bar(x: &RefCell<u32>) {
{
let mut y = x.borrow_mut();
*y += 1;
} // y dropped here at end of scope
baz().await;
}
From the Clippy lint list (0.1.99), part of the Rust project, MIT or Apache-2.0. Official entry.
Related lints
- arc_with_non_send_syncarc with non send sync
- await_holding_invalid_typeAllows users to configure types which should not be held across await suspension points
- await_holding_lockChecks for calls to await while holding a non-async-aware MutexGuard
- blanket_clippy_restriction_lints`clippy::restriction` is not meant to be enabled as a group
- block_scrutineeWarns when a match, if let, or while let scrutinee is wrapped in a block. This lint only triggers on the 2021 edition and older
- by_ref_peekable_peekcalling `.by_ref().peekable().peek()` will advance the underlying iterator and consume its first output
All 847 Clippy lints · Rust compiler errors · Cargo.toml checker
Up next
Related lintclippy::arc_with_non_send_syncarc with non send syncRead it next →Did this answer your question?