Strange inference failure with `Arc::new_cyclic`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
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
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
Reproduce the example in the playground's src/lib.rs with the reported rustc 1.88.0-nightly toolchain, focusing on Arc::<_>::new_cyclic and the closure's Weak type inference. Trace the behavior behind E0282 and E0609; done means explaining why the this.thing use changes inference and validating the resulting compiler behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100