rust-lang / rust-lang/rust-clippy
False positive for `await_holding_refcell_ref`: RefMut for keeping the awaited future alive
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
Lint name: await_holding_refcell_ref
I tried this code:
#[wasm_bindgen]
struct IntoUnderlyingSink {
inner: Rc<RefCell<Inner>>,
}
#[wasm_bindgen]
impl IntoUnderlyingSink {
pub fn write(&mut self, chunk: JsValue) -> Promise {
let inner = self.inner.clone();
future_to_promise(async move {
let mut inner = inner.try_borrow_mut().unwrap_throw();
inner.write(chunk).await.map(|_| JsValue::undefined())
})
}
}
impl Inner {
async fn write(&mut self, chunk: JsValue) -> Result<(), JsValue> {
// ...
}
}
(For more context, see the complete code.)
This might seem a bit of a contrived example, but it's actually the only way I found to use async fn inside a Rust struct exported to JavaScript with wasm-bindgen. 🤷 (Better suggestions are welcome though!)
I expected to see this happen: No error since the RefMut is necessary to keep the inner.write(chunk) future alive.
Instead, this happened: Causes a warning.
error: this RefCell Ref is held across an 'await' point. Consider ensuring the Ref is dropped before calling await.
--> src\writable\into_underlying_sink.rs:30:17
|
30 | let mut inner = inner.try_borrow_mut().unwrap_throw();
| ^^^^^^^^^
|
= note: `#[deny(clippy::await_holding_refcell_ref)]` on by default
note: these are all the await points this ref is held through
--> src\writable\into_underlying_sink.rs:30:13
|
30 | / let mut inner = inner.try_borrow_mut().unwrap_throw();
31 | | inner.write(chunk).await.map(|_| JsValue::undefined())
32 | | })
| |_________^
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_refcell_ref
Meta
cargo clippy -V: clippy 0.0.212 (e1884a8e 2020-12-29)rustc -Vv:rustc 1.49.0 (e1884a8e3 2020-12-29) binary: rustc commit-hash: e1884a8e3c3e813aada8254edfa120e85bf5ffca commit-date: 2020-12-29 host: x86_64-pc-windows-msvc release: 1.49.0
I noticed that this particular lint was already downgraded in #6354 for Rust 1.50 (currently in beta). I can confirm that the warning does not show up when using Rust beta or nightly with the default settings. Since it only shows up in Rust 1.49, I worked around it on my end by disabling this lint.
Still, I opened this issue since I think this might be an interesting false positive. Feel free to close if you disagree, no hard feelings. 🙂
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the await_holding_refcell_ref warning with the Rust example and the linked src/writable/into_underlying_sink.rs code. Read the lint entry point and its existing tests, then verify that a RefMut needed to keep an awaited future alive is no longer reported while genuine RefCell references held across await points remain diagnosed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, wasm
- Domain
- devtools, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100