rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
96.77k stars 12.5k forks source link

Cycle detected when optimizing MIR on nightly #129811

Closed chvck closed 1 week ago

chvck commented 2 weeks ago

Originally posted at https://users.rust-lang.org/t/cycle-detected-when-optimizing-mir-on-nightly/116849/1 and filing this upon request from @bjorn3 .

We're using nightly rust and as of nightly-2024-08-29 (prior to this it compiled fine) we see the following error:

error[E0391]: cycle detected when optimizing MIR for `crudcomponent::<impl at sdk/couchbase-core/src/crudcomponent.rs:38:1: 44:41>::orchestrate_simple_crud::{closure#0}::{closure#0}::{closure#0}::{closure#1}`
   --> sdk/couchbase-core/src/crudcomponent.rs:156:78
    |
156 |           orchestrate_retries(self.retry_manager.clone(), retry_info, async || {
    |  ______________________________________________________________________________^
157 | |             orchestrate_memd_collection_id(
158 | |                 self.collections.clone(),
159 | |                 scope_name,
...   |
188 | |             .await
189 | |         })
    | |_________^
    |
    = note: ...which immediately requires optimizing MIR for `crudcomponent::<impl at sdk/couchbase-core/src/crudcomponent.rs:38:1: 44:41>::orchestrate_simple_crud::{closure#0}::{closure#0}::{closure#0}::{closure#1}` again
    = note: cycle used when computing layout of `{async closure body@sdk/couchbase-core/src/crudcomponent.rs:156:78: 189:10}`
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

For more information about this error, try `rustc --explain E0391`.
error: could not compile `rscbx_couchbase_core` (lib) due to 1 previous error

Function being flagged can be viewed at couchbase-rs/sdk/couchbase-core/src/crudcomponent.rs at nativex · couchbaselabs/couchbase-rs · GitHub. We're having a bit of a hard time debugging this issue, it's not very clear what this actually means. I've tried looking at the HIR output but it didn't really help and I'm a bit lost on this one as I'm not familiar with MIR.

I expected to see this happen: Compilation succeed.

Instead, this happened: Compilation failed due to MIR cycle.

Meta

rustc --version --verbose:

rustc 1.82.0-nightly (0d634185d 2024-08-29)
binary: rustc
commit-hash: 0d634185dfddefe09047881175f35c65d68dcff1
commit-date: 2024-08-29
host: aarch64-apple-darwin
release: 1.82.0-nightly
LLVM version: 19.1.0

Backtrace contained no extra information.

matthiaskrgr commented 2 weeks ago

this kind of looks like it should be an ICE instead? :thinking:

compiler-errors commented 2 weeks ago

@chvck: I'll try to put up a fix.

We're having a bit of a hard time debugging this issue [...]

It's due to #128506 (not that you need to understand what that PR does), not your fault.

compiler-errors commented 2 weeks ago

For now, though, you'll need to either stop using async || {} closures (since you've got an impl Fn() -> Fut bound, not impl async Fn(); why are you using async || {} closures over just || async {}, since those don't really buy you anything in this case?) or pin your nightly compiler version until I can minimize this and fix it.

theemathas commented 1 week ago

Minimized:

#![feature(async_closure)]

use std::future::Future;

async fn orchestrate_memd_routing<Fut: Future>(operation: impl Fn() -> Fut) {
    operation().await;
}

pub async fn orchestrate_simple_crud() {
    orchestrate_memd_routing(async || async {}.await).await;
}

To reproduce: cargo +nightly build

(Odd that the "optimization" also happens in debug builds.)

Of note: During the minimization process, rust-analyzer froze multiple times. And a few times, cargo +nightly build also froze.

compiler-errors commented 1 week ago

@theemathas you're awesome! thanks for the minimization.

chvck commented 1 week ago

It's due to https://github.com/rust-lang/rust/pull/128506 (not that you need to understand what that PR does), not your fault.

Thanks for confirming.

For now, though, you'll need to either stop using async || {} closures (since you've got an impl Fn() -> Fut bound, not impl async Fn(); why are you using async || {} closures over just || async {}, since those don't really buy you anything in this case?) or pin your nightly compiler version until I can minimize this and fix it.

We were having a lot of issues with lifetimes when using the async blocks which lead to us using async closures instead. Possibly we should just revisit that...

theemathas commented 1 week ago

@chvck You might be interested in these two links for an explanation on how exactly async closures differ from a closure that returns an async block:

https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing.html

https://rust-lang.github.io/rfcs/3668-async-closures.html

chvck commented 1 week ago

Thanks @theemathas I'll take a look at those.