Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

by_move_body.rs:275:21: There should be at least a single deref for an upvar local initialization, found [] #138501

Closed
TeamDman opened this issue Mar 14, 2025 · 1 comment · Fixed by #138514
Assignees
Labels
A-async-closures `async || {}` C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@TeamDman
Copy link

TeamDman commented Mar 14, 2025

Code

This compiler error appeared when I tried to wrap my function in an async block so I could use inner returns without returning from the parent fn; I want to call .wrap_err from eyre crate on whatever is returning so I can attach some information.

I had previously attempted to use the unstable try_blocks feature, but I think my return Err and bail! usage in the body was returning from the fn instead of the try block.

removing the wrapping async closure fixes the rustc-ice compiler error.

AAFC-Cloud/Cloud-Terrastodon@fc55eb8

diff --git a/rust/crates/command/src/command.rs b/rust/crates/command/src/command.rs
index 10f645d..9c52993 100644
--- a/rust/crates/command/src/command.rs
+++ b/rust/crates/command/src/command.rs
@@ -550,7 +550,7 @@ impl CommandBuilder {
     #[async_recursion]
     #[track_caller]
     pub async fn run_raw(&self) -> Result<CommandOutput> {
-        let result: eyre::Result<CommandOutput> = (async ||{
+        // let result: eyre::Result<CommandOutput> = (async ||{
             // Check cache
             match self.get_cached_output().await {
                 Ok(None) => {}
@@ -685,10 +685,10 @@ impl CommandBuilder {
 
             // Return success
             Ok(output)
-        })().await;
-        result
-            .wrap_err(format!("Invoking command `{}`", self.summarize()))
-            .wrap_err(format!("Called from {}", std::panic::Location::caller()))
+        // })().await;
+        // result
+        //     .wrap_err(format!("Invoking command `{}`", self.summarize()))
+        //     .wrap_err(format!("Called from {}", std::panic::Location::caller()))
     }
 
     pub async fn run<T>(&self) -> Result<T>

here is the permalink to the relevant file at the commit where the compiler error manifests

https://github.com/AAFC-Cloud/Cloud-Terrastodon/blob/73709d3861d008195bb14824e1fc1bb0f03c1940/rust/crates/command/src/command.rs#L553

cd cloud_terrastodon/rust
cargo build

rustc-ice-2025-03-14T14_54_32-34820.txt

Meta

rustc --version --verbose:

rustc 1.87.0-nightly (f8a913b13 2025-02-23)
binary: rustc
commit-hash: f8a913b1381e90379c7ca63ac2b88b9518936628
commit-date: 2025-02-23
host: x86_64-pc-windows-msvc
release: 1.87.0-nightly
LLVM version: 20.1.0

Error output

cargo build 2>&1 | set-clipboard

Backtrace

Compiling cloud_terrastodon_core_command v0.1.0 (C:\Users\redacted\source\repos\cloud-terrastodon\rust\crates\command)
error: internal compiler error: compiler\rustc_mir_transform\src\coroutine\by_move_body.rs:275:21: There should be at least a single deref for an upvar local initialization, found []
System.Management.Automation.RemoteException
System.Management.Automation.RemoteException
thread 'rustc' panicked at compiler\rustc_mir_transform\src\coroutine\by_move_body.rs:275:21:
Box<dyn Any>
stack backtrace:
   0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
   1: <rustc_errors::diagnostic::BugAbort as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
   2: rustc_middle::util::bug::span_bug_fmt::<rustc_span::span_encoding::Span>
   3: <rustc_middle::ty::consts::Const>::to_value
   4: <rustc_middle::ty::consts::Const>::to_value
   5: rustc_middle::util::bug::bug_fmt
   6: <rustc_mir_transform::coroutine::by_move_body::MakeByMoveBody as rustc_middle::mir::visit::MutVisitor>::visit_place
   7: rustc_mir_transform::coroutine::by_move_body::coroutine_by_move_body_def_id
   8: <rustc_query_impl::plumbing::QueryCtxt as rustc_query_system::query::QueryContext>::depth_limit_error
   9: RINvNtNtCs9MBRoav2AsG_18rustc_query_system5query8plumbing17try_execute_queryINtCsk7G2C29L4pP_16rustc_query_impl13DynamicConfigINtNtB4_6caches10DefIdCacheINtNtNtCsiF0U1sNts3Z_12rustc_middle5query5erase6ErasedAhj8_EEKb0_KB3r_KB3r_ENtNtB1f_8plumbing9QueryCtxt
  10: <rustc_span::def_id::DefIndex as rustc_query_impl::profiling_support::SpecIntoSelfProfilingString>::spec_to_self_profile_string
  11: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  12: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  13: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  14: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  15: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  16: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  17: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  18: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  19: <std::io::buffered::bufwriter::BufWriter<std::io::stdio::Stdout>>::write_all_cold
  20: <rayon_core::registry::WorkerThread>::wait_until_cold
  21: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  22: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  23: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  24: core::slice::sort::unstable::heapsort::heapsort::<(alloc::string::String, core::option::Option<alloc::string::String>), <(alloc::string::String, core::option::Option<alloc::string::String>) as core::cmp::PartialOrd>::lt>
  25: <std::io::buffered::bufwriter::BufWriter<std::io::stdio::Stdout>>::write_all_cold
  26: <rayon_core::registry::WorkerThread>::wait_until_cold
  27: <rayon_core::registry::ThreadBuilder>::run
  28: core::slice::sort::unstable::heapsort::heapsort::<((rustc_lint_defs::Level, &str), usize), <((rustc_lint_defs::Level, &str), usize) as core::cmp::PartialOrd>::lt>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
System.Management.Automation.RemoteException
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
System.Management.Automation.RemoteException
note: please make sure that you have updated to the latest nightly
System.Management.Automation.RemoteException
note: please attach the file at `C:\Users\redacted\source\repos\cloud-terrastodon\rust\rustc-ice-2025-03-14T14_57_11-50832.txt` to your bug report
System.Management.Automation.RemoteException
note: compiler flags: --crate-type lib -C embed-bitcode=no -C debuginfo=2 -C linker=rust-lld.exe -C incremental=[REDACTED] -Z share-generics=n -Z threads=0
System.Management.Automation.RemoteException
note: some of the compiler flags provided by cargo are hidden
System.Management.Automation.RemoteException
query stack during panic:
#0 [coroutine_by_move_body_def_id] looking up the coroutine by-move body for `command::<impl at crates\command\src\command.rs:288:1: 288:20>::run_raw::{closure#0}::{closure#0}::{closure#0}`
#1 [analysis] running analysis passes on this crate
end of query stack
error: could not compile `cloud_terrastodon_core_command` (lib)
System.Management.Automation.RemoteException
Caused by:
  process didn't exit successfully: `C:\Users\redacted\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\bin\rustc.exe --crate-name cloud_terrastodon_core_command --edition=2021 crates\command\src\lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 --check-cfg cfg(docsrs,test) --check-cfg "cfg(feature, values())" -C metadata=7558873a441101e7 -C extra-filename=-906ad886c3cb402d --out-dir C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps -C linker=rust-lld.exe -C incremental=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\incremental -L dependency=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps --extern async_recursion=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\async_recursion-24df221e7790a2db.dll --extern bstr=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libbstr-82862611855a3537.rmeta --extern chrono=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libchrono-8ee824a437ee4af8.rmeta --extern cloud_terrastodon_core_config=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libcloud_terrastodon_core_config-45cda0b2a2da8de7.rmeta --extern cloud_terrastodon_core_pathing=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libcloud_terrastodon_core_pathing-8bbdaf14ed44524a.rmeta --extern eyre=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libeyre-eb83050ece3d9ca1.rmeta --extern humantime=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libhumantime-045845348c46c495.rmeta --extern serde=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libserde-54f8f08d0ba9b293.rmeta --extern serde_json=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libserde_json-eec54a34af6fe8ed.rmeta --extern tempfile=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libtempfile-cc63fcd40fb8f7fc.rmeta --extern tokio=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libtokio-5857200c6177bf15.rmeta --extern tracing=C:\Users\redacted\source\repos\cloud-terrastodon\rust\target\debug\deps\libtracing-c4553737279fd8ba.rmeta -Zshare-generics=n -Zthreads=0 -L native=C:\Users\redacted\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\windows_x86_64_msvc-0.52.6\lib -L native=C:\Users\redacted\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\windows_x86_64_msvc-0.48.5\lib` (exit code: 101)


I tried getting a smaller reproduction but was unsuccessful. The following code builds and runs without errors.

This compiles and runs properly
use eyre::Context;

#[tokio::main]
async fn main() -> eyre::Result<()> {
    println!("Hello, world!");
    let bruh = Bruh {
        name: "hehe".to_string(),
    };
    // Call once; if it recurses, you might see the ICE.
    bruh.bruh().await?;
    Ok(())
}

struct Bruh {
    pub name: String,
}

impl Bruh {
    #[async_recursion::async_recursion]
    #[track_caller]
    pub async fn bruh(&self) -> eyre::Result<i32> {
        let result: eyre::Result<i32> = (async || {
            println!("Level 1: {}", self.name);
            // Nest a second async closure:
            let inner = async || {
                println!("Level 2: {}", self.name);
                // Nest a third async closure:
                let inner_most = async || {
                    println!("Level 3: {}", self.name);
                    Ok(1)
                };
                inner_most().await
            };
            inner().await
        })()
        .await;
        result.wrap_err(format!("Called from {}", std::panic::Location::caller()))
    }
}

/*

[dependencies]
async-recursion = "1.1.1"
eyre = "0.6.12"
tokio = { version = "1.44.1", features = ["full"] }

*/
@TeamDman TeamDman added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 14, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 14, 2025
@cyrgani
Copy link
Contributor

cyrgani commented Mar 14, 2025

reduction:

enum Foo {
    A,
    B,
}

fn run_raw(f: &Foo) {
    async || match f {
        Foo::B if true => {
            run_raw(f);
        }
        _ => {}
    };
}

@rustbot label S-has-mcve F-async_closure

@rustbot rustbot added A-async-closures `async || {}` S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue labels Mar 14, 2025
@compiler-errors compiler-errors self-assigned this Mar 14, 2025
@bors bors closed this as completed in 81ba557 Mar 15, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Mar 15, 2025
Rollup merge of rust-lang#138514 - compiler-errors:fake-borrow-ref-to-value, r=oli-obk

Remove fake borrows of refs that are converted into non-refs in `MakeByMoveBody`

Remove fake borrows of closure captures if that capture has been replaced with a by-move version of that capture.

For example, given an async closure that looks like:

```
let f: Foo;
let c = async move || {
    match f { ... }
};
```

... in this pair of coroutine-closure + coroutine, we capture `Foo` in the parent and `&Foo` in the child. We will emit two fake borrows like:

```
_2 = &fake shallow (*(_1.0: &Foo));
_3 = &fake shallow (_1.0: &Foo);
```

However, since the by-move-body transform is responsible for replacing `_1.0: &Foo` with `_1.0: Foo` (since the `AsyncFnOnce` coroutine will own `Foo` by value), that makes the second fake borrow obsolete since we never have an upvar of type `&Foo`, and we should replace it with a `nop`.

As a side-note, we don't actually even care about fake borrows here at all since they're fully a MIR borrowck artifact, and we don't need to borrowck by-move MIR bodies. But it's best to preserve as much as we can between these two bodies :)

Fixes rust-lang#138501

r? oli-obk
@jieyouxu jieyouxu removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-closures `async || {}` C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants