rust-lang / rust-lang/rust-clippy

`clippy::await_holding_refcell_ref` appears to assume out-of-scope variables are being held across await points

Open
#10,124 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

The following code

use anyhow::Error;
use std::cell::RefCell;

pub struct Outer {
    inner: RefCell<Inner>,
}

impl Outer {
    pub fn new() -> Self {
        Self {
            inner: RefCell::new(Inner {
                val: 0,
                flag: false,
            }),
        }
    }
}

pub struct Inner {
    val: u32,
    flag: bool,
}

impl Inner {
    
    fn val(&self) -> u32 {
        self.val
    }
}

pub async fn do_something() -> Result<(), Error> {
    let outer = Outer::new();
    if let Some(val) = {
        let inner = outer.inner.borrow();
        inner.flag.then(move || inner.val())
    } {
        do_something_else(val).await?;
    }
    Ok(())
}

async fn do_something_else(val: u32) -> Result<(), Error> {
    println!("{val}");
    Ok(())
}

yields the following unexpected clippy warning:

warning: this `RefCell` reference is held across an `await` point
  --> src/lib.rs:37:9
   |
37 |         inner.flag.then(move || inner.val())
   |         ^^^^^
   |
   = help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through
  --> src/lib.rs:35:5
   |
35 | /     if let Some(val) = {
36 | |         let inner = outer.inner.borrow();
37 | |         inner.flag.then(move || inner.val())
38 | |     } {
39 | |         do_something_else(val).await?;
40 | |     }
   | |_____^
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_refcell_ref
   = note: `#[warn(clippy::await_holding_refcell_ref)]` on by default

This probably falls under rust-lang/rust#69663.

Playground link

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=75f2f97ff4f11d2d957b25df47d61c26

Meta
Nightly channel
Build using the Nightly version: 1.68.0-nightly

(2022-12-27 92c1937a90e5b6f20fa6)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the warning with the provided Playground link and the example in src/lib.rs, then inspect the implementation of the await_holding_refcell_ref lint. The fix is complete when an out-of-scope RefCell reference no longer produces this warning while genuinely held references still do.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.