-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #6029 - Daniel-B-Smith:refcell_ref_await, r=flip1995
Add lint for holding RefCell Ref across an await Fixes #6008 This introduces the lint await_holding_refcell_ref. For async functions, we iterate over all types in generator_interior_types and look for `core::cell::Ref` or `core::cell::RefMut`. If we find one then we emit a lint. Heavily cribs from: #5439 changelog: introduce the await_holding_refcell_ref lint
- Loading branch information
Showing
7 changed files
with
257 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// edition:2018 | ||
#![warn(clippy::await_holding_refcell_ref)] | ||
|
||
use std::cell::RefCell; | ||
|
||
async fn bad(x: &RefCell<u32>) -> u32 { | ||
let b = x.borrow(); | ||
baz().await | ||
} | ||
|
||
async fn bad_mut(x: &RefCell<u32>) -> u32 { | ||
let b = x.borrow_mut(); | ||
baz().await | ||
} | ||
|
||
async fn good(x: &RefCell<u32>) -> u32 { | ||
{ | ||
let b = x.borrow_mut(); | ||
let y = *b + 1; | ||
} | ||
baz().await; | ||
let b = x.borrow_mut(); | ||
47 | ||
} | ||
|
||
async fn baz() -> u32 { | ||
42 | ||
} | ||
|
||
async fn also_bad(x: &RefCell<u32>) -> u32 { | ||
let first = baz().await; | ||
|
||
let b = x.borrow_mut(); | ||
|
||
let second = baz().await; | ||
|
||
let third = baz().await; | ||
|
||
first + second + third | ||
} | ||
|
||
async fn less_bad(x: &RefCell<u32>) -> u32 { | ||
let first = baz().await; | ||
|
||
let b = x.borrow_mut(); | ||
|
||
let second = baz().await; | ||
|
||
drop(b); | ||
|
||
let third = baz().await; | ||
|
||
first + second + third | ||
} | ||
|
||
async fn not_good(x: &RefCell<u32>) -> u32 { | ||
let first = baz().await; | ||
|
||
let second = { | ||
let b = x.borrow_mut(); | ||
baz().await | ||
}; | ||
|
||
let third = baz().await; | ||
|
||
first + second + third | ||
} | ||
|
||
#[allow(clippy::manual_async_fn)] | ||
fn block_bad(x: &RefCell<u32>) -> impl std::future::Future<Output = u32> + '_ { | ||
async move { | ||
let b = x.borrow_mut(); | ||
baz().await | ||
} | ||
} | ||
|
||
fn main() { | ||
let rc = RefCell::new(100); | ||
good(&rc); | ||
bad(&rc); | ||
bad_mut(&rc); | ||
also_bad(&rc); | ||
less_bad(&rc); | ||
not_good(&rc); | ||
block_bad(&rc); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. | ||
--> $DIR/await_holding_refcell_ref.rs:7:9 | ||
| | ||
LL | let b = x.borrow(); | ||
| ^ | ||
| | ||
= note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings` | ||
note: these are all the await points this ref is held through | ||
--> $DIR/await_holding_refcell_ref.rs:7:5 | ||
| | ||
LL | / let b = x.borrow(); | ||
LL | | baz().await | ||
LL | | } | ||
| |_^ | ||
|
||
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. | ||
--> $DIR/await_holding_refcell_ref.rs:12:9 | ||
| | ||
LL | let b = x.borrow_mut(); | ||
| ^ | ||
| | ||
note: these are all the await points this ref is held through | ||
--> $DIR/await_holding_refcell_ref.rs:12:5 | ||
| | ||
LL | / let b = x.borrow_mut(); | ||
LL | | baz().await | ||
LL | | } | ||
| |_^ | ||
|
||
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. | ||
--> $DIR/await_holding_refcell_ref.rs:33:9 | ||
| | ||
LL | let b = x.borrow_mut(); | ||
| ^ | ||
| | ||
note: these are all the await points this ref is held through | ||
--> $DIR/await_holding_refcell_ref.rs:33:5 | ||
| | ||
LL | / let b = x.borrow_mut(); | ||
LL | | | ||
LL | | let second = baz().await; | ||
LL | | | ||
... | | ||
LL | | first + second + third | ||
LL | | } | ||
| |_^ | ||
|
||
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. | ||
--> $DIR/await_holding_refcell_ref.rs:45:9 | ||
| | ||
LL | let b = x.borrow_mut(); | ||
| ^ | ||
| | ||
note: these are all the await points this ref is held through | ||
--> $DIR/await_holding_refcell_ref.rs:45:5 | ||
| | ||
LL | / let b = x.borrow_mut(); | ||
LL | | | ||
LL | | let second = baz().await; | ||
LL | | | ||
... | | ||
LL | | first + second + third | ||
LL | | } | ||
| |_^ | ||
|
||
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. | ||
--> $DIR/await_holding_refcell_ref.rs:60:13 | ||
| | ||
LL | let b = x.borrow_mut(); | ||
| ^ | ||
| | ||
note: these are all the await points this ref is held through | ||
--> $DIR/await_holding_refcell_ref.rs:60:9 | ||
| | ||
LL | / let b = x.borrow_mut(); | ||
LL | | baz().await | ||
LL | | }; | ||
| |_____^ | ||
|
||
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await. | ||
--> $DIR/await_holding_refcell_ref.rs:72:13 | ||
| | ||
LL | let b = x.borrow_mut(); | ||
| ^ | ||
| | ||
note: these are all the await points this ref is held through | ||
--> $DIR/await_holding_refcell_ref.rs:72:9 | ||
| | ||
LL | / let b = x.borrow_mut(); | ||
LL | | baz().await | ||
LL | | } | ||
| |_____^ | ||
|
||
error: aborting due to 6 previous errors | ||
|