Description
In tokio 0.2, there was a footgun: if you created a const Runtime
, then each time you called runtime.block_on()
it would make a new runtime. This lead to confusing errors at runtime like 'reactor gone' which gave no hint of what actually went wrong: rust-lang/rust-clippy#6088
Fortunately, this was fixed by const_item_mutation
in #75573. Unfortunately, Runtime::block_on
will now take &self
instead of &mut self
starting in tokio 0.3: https://tokio.rs/blog/2020-10-tokio-0-3
Runtime
can now only be constructed at runtime: as a local variable or in a once_cell
, or lazy_static
. The code for that looks like this:
use once_cell::sync::Lazy;
use tokio::runtime::Runtime;
const RUNTIME: Lazy<Runtime> = Lazy::new(|| {
Runtime::new().unwrap()
});
fn main() {
RUNTIME.block_on(async {});
}
rustc will compile this without a warning. Clippy, however, says that this is almost certainly not what you want:
error: a `const` item should never be interior mutable
--> src/main.rs:4:1
|
4 | const RUNTIME: Lazy<Runtime> = Lazy::new(|| {
| ^----
| |
| _make this a static item (maybe with lazy_static)
| |
5 | | Runtime::new().unwrap()
6 | | });
| |___^
|
= note: `#[deny(clippy::declare_interior_mutable_const)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const
error: a `const` item with interior mutability should not be borrowed
--> src/main.rs:9:5
|
9 | RUNTIME.block_on(async {});
| ^^^^^^^
|
= note: `#[deny(clippy::borrow_interior_mutable_const)]` on by default
= help: assign this const to a local or static variable, and use the variable here
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const
To avoid having this footgun, the lint should be uplifted from clippy to rustc (possibly as warn-by-default), so that users will notice it even if they don't use clippy.
cc @Darksonn