Open
Description
I tried this code (playground):
#![allow(unused)]
use std::sync::Arc;
use tokio_util::task::AbortOnDropHandle;
pub struct Foo {
thing: Thing,
task: AbortOnDropHandle<()>,
}
impl Foo {
pub fn new() -> Arc<Self> {
// Fix 1: replace `<_>` with `<Self>`
Arc::<_>::new_cyclic(|weak| {
let weak = weak.clone();
let handler = async move {
async { /* ... */ }.await; // waiting for some event
if let Some(this) = weak.upgrade() {
// "Fix" 2: comment out this line
this.thing.do_thing();
}
};
Foo {
thing: Thing,
task: AbortOnDropHandle::new(tokio::spawn(handler)),
}
})
}
}
struct Thing;
impl Thing {
fn do_thing() { unimplemented!() }
}
I expected to see this happen: It compiles
Instead, this happened: It does not compile
I find it very strange the type inference is unable to figure out that
a. new_cyclic
returns an Arc<Self>
b. the closure returns a Foo
I find it even stranger that commenting out the line where the inner value is used ("Fix" 2) makes it compile.
Compiler Error:
Compiling playground v0.0.1 (/playground)
error[E0282]: type annotations needed for `&std::sync::Weak<_>`
--> src/lib.rs:14:31
|
14 | Arc::<_>::new_cyclic(|weak| {
| ^^^^
...
21 | this.thing.do_thing();
| ---------- type must be known at this point
|
help: consider giving this closure parameter an explicit type, where the type for type parameter `T` is specified
|
14 | Arc::<_>::new_cyclic(|weak: &std::sync::Weak<T>| {
| +++++++++++++++++++++
error[E0609]: no field `thing` on type `Arc<_>`
--> src/lib.rs:21:26
|
21 | this.thing.do_thing();
| ^^^^^ unknown field
Some errors have detailed explanations: E0282, E0609.
For more information about an error, try `rustc --explain E0282`.
error: could not compile `playground` (lib) due to 2 previous errors
rustc version:
rustc 1.88.0-nightly (9ffde4b08 2025-04-12)
binary: rustc
commit-hash: 9ffde4b089fe8e43d5891eb517001df27a8443ff
commit-date: 2025-04-12
host: x86_64-unknown-linux-gnu
release: 1.88.0-nightly
LLVM version: 20.1.2