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

Internal Compiler Error with awaited async closure within impl Future fn poll #124867

Open
bionicles opened this issue May 7, 2024 · 1 comment · May be fixed by #125306
Open

Internal Compiler Error with awaited async closure within impl Future fn poll #124867

bionicles opened this issue May 7, 2024 · 1 comment · May be fixed by #125306
Assignees
Labels
C-bug Category: This is a bug. F-async_closure `#![feature(async_closure)]` 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.

Comments

@bionicles
Copy link

bionicles commented May 7, 2024

Code

Rustc panicked when I attempted to use async in poll.

I wanted to compose an async task inside my custom future

// to listen for the hello world messages, run this in a separate terminal
// ncat -k -l 8080
use anyhow::Result as AnyhowResult;
use futures::FutureExt;
use std::{
    future::Future,
    pin::Pin,
    task::{Context, Poll},
    time::Duration,
};
use tokio::{io::AsyncWriteExt, net, runtime, task};

/// A Future to print "hello world!\n" on a TCP Stream with a sleep interval and iteration number.
struct SleepyHelloWorld {
    handle: runtime::Handle,
    stream: net::TcpStream,
    sleep_millis: u64,
    n_hello: usize,
}

impl SleepyHelloWorld {
    async fn write_one(&mut self, src: &[u8]) -> AnyhowResult<()> {
        self.stream.write_all(src).await;
        Ok(())
    }
}

impl Future for SleepyHelloWorld {
    type Output = AnyhowResult<()>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let waker = cx.waker().clone();

        let n_hello = self.n_hello; // copy
        let duration = Duration::from_millis(self.sleep_millis);
        let greeting = b"hello world!\n";

        let this = Pin::get_mut(self);

        // run a task on a blocking thread (because fn poll is sync)
        let task = async move |this: &mut Self| {
            for _ in 0..n_hello {
                this.write_one(greeting).await?;
                tokio::time::sleep(duration).await;
                waker.wake();
            }
            Result::<(), anyhow::Error>::Ok(())
        };

        // move that workload into a blocking thread
        let mut owned_handle = task::spawn_blocking(move || self.handle.block_on(task(this)));
        let mut handle = Pin::new(&mut owned_handle);

        // Schedule the future to be woken up when the task is complete.
        let waker = cx.waker().clone();

        // Poll the handle to completion.
        match handle.as_mut().poll(cx) {
            Poll::Ready(result) => {
                println!("The task completed, so we're done.\nresult={result:#?}");
                match result {
                    Ok(_) => Poll::Ready(Ok(())),
                    Err(e) => Poll::Ready(Err(e.into())),
                }
            }
            Poll::Pending => {
                // The task is still running, so we need to wait.
                Poll::Pending
            }
        }
    }
}

#[tokio::main(flavor = "current_thread")]
async fn main() -> AnyhowResult<()> {
    println!("Connecting.");
    let sleepy_future = SleepyHelloWorld {
        handle: runtime::Handle::current(),
        stream: net::TcpStream::connect("127.0.0.1:8080").await?,
        sleep_millis: 350,
        n_hello: 10,
    };
    println!("Connected.");

    println!("Awaiting sleepy_future...");
    sleepy_future.await;
    println!("Awaiting sleepy_future... done.");

    Ok(())
}

Meta

rustc --version --verbose:

> rustc --version --verbose
rustc 1.80.0-nightly (7d83a4c13 2024-05-06)
binary: rustc
commit-hash: 7d83a4c131ab9ae81a74c6fd825c827d74a2881d
commit-date: 2024-05-06
host: x86_64-unknown-linux-gnu
release: 1.80.0-nightly
LLVM version: 18.1.4

Error output

error: the compiler unexpectedly panicked. this is a bug.

note: compiler flags: -Z unstable-options --crate-type bin -C embed-bitcode=no -C debuginfo=2 -C incremental=[REDACTED]

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [mir_built] building MIR for `<impl at examples/with_tokio.rs:27:1: 27:33>::poll::{closure#0}::{closure#0}`
#1 [check_unsafety] unsafety-checking `<impl at examples/with_tokio.rs:27:1: 27:33>::poll`
#2 [analysis] running analysis passes on this crate
end of query stack
thread 'rustc' panicked at compiler/rustc_mir_transform/src/coroutine/by_move_body.rs:140:21:
assertion `left != right` failed: `FnOnce` coroutine-closures return coroutines that capture from their body; it will always result in a borrowck error!
  left: FnOnce
 right: FnOnce
stack backtrace:
   0:     0x7f70ebd8cb35 - std::backtrace_rs::backtrace::libunwind::trace::h918aaf6e60cc0a20
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/../../backtrace/src/backtrace/libunwind.rs:105:5
   1:     0x7f70ebd8cb35 - std::backtrace_rs::backtrace::trace_unsynchronized::h2eac6c94b93f8e3c
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x7f70ebd8cb35 - std::sys_common::backtrace::_print_fmt::h8e5edaeb6a4352e8
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/sys_common/backtrace.rs:68:5
   3:     0x7f70ebd8cb35 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hf5cc6736d08af678
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/sys_common/backtrace.rs:44:22
   4:     0x7f70ebddbcfb - core::fmt::rt::Argument::fmt::hb75c12041eb78bdc
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/core/src/fmt/rt.rs:165:63
   5:     0x7f70ebddbcfb - core::fmt::write::h3e6a6276a812b52d
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/core/src/fmt/mod.rs:1157:21
   6:     0x7f70ebd8187f - std::io::Write::write_fmt::h1eb4d2f52c7badcc
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/io/mod.rs:1835:15
   7:     0x7f70ebd8c90e - std::sys_common::backtrace::_print::h027a355b4099d109
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/sys_common/backtrace.rs:47:5
   8:     0x7f70ebd8c90e - std::sys_common::backtrace::print::h9288434216016cb8
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/sys_common/backtrace.rs:34:9
   9:     0x7f70ebd8f279 - std::panicking::default_hook::{{closure}}::hb774f76bb0cbe3f3
  10:     0x7f70ebd8efbd - std::panicking::default_hook::h5e6bb2fe4f610e68
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/panicking.rs:298:9
  11:     0x7f70eeeb3d1f - std[2409bda48c37ea6b]::panicking::update_hook::<alloc[e4f27f1b259856c9]::boxed::Box<rustc_driver_impl[3b65384176704029]::install_ice_hook::{closure#0}>>::{closure#0}
  12:     0x7f70ebd8f976 - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h150247b09595b272
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/alloc/src/boxed.rs:2036:9
  13:     0x7f70ebd8f976 - std::panicking::rust_panic_with_hook::h193842b19bca8c30
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/panicking.rs:799:13
  14:     0x7f70ebd8f724 - std::panicking::begin_panic_handler::{{closure}}::h9e341f02e94749d0
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/panicking.rs:664:13
  15:     0x7f70ebd8cff9 - std::sys_common::backtrace::__rust_end_short_backtrace::ha4420d007785945b
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/sys_common/backtrace.rs:171:18
  16:     0x7f70ebd8f457 - rust_begin_unwind
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/panicking.rs:652:5
  17:     0x7f70ebdd82c3 - core::panicking::panic_fmt::h0afd8a3c11e985b9
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/core/src/panicking.rs:72:14
  18:     0x7f70ebdd888f - core::panicking::assert_failed_inner::h1ec36149f8f0af66
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/core/src/panicking.rs:403:23
  19:     0x7f70ef4abc18 - core[e58631ecc326099b]::panicking::assert_failed::<rustc_type_ir[c154581ae42d6ad0]::ClosureKind, rustc_type_ir[c154581ae42d6ad0]::ClosureKind>
  20:     0x7f70edf3dba6 - <rustc_mir_transform[ed70598d93e22d13]::coroutine::by_move_body::ByMoveBody as rustc_middle[d85377d387f08e9a]::mir::MirPass>::run_pass
  21:     0x7f70f020184d - rustc_mir_transform[ed70598d93e22d13]::pass_manager::run_passes_inner
  22:     0x7f70f04c9a28 - rustc_query_impl[f7d6eb8805e88c29]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[f7d6eb8805e88c29]::query_impl::mir_built::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d85377d387f08e9a]::query::erase::Erased<[u8; 8usize]>>
  23:     0x7f70f0527c52 - rustc_query_system[bd604859ea317a95]::query::plumbing::try_execute_query::<rustc_query_impl[f7d6eb8805e88c29]::DynamicConfig<rustc_query_system[bd604859ea317a95]::query::caches::VecCache<rustc_span[86ddde2698e45e98]::def_id::LocalDefId, rustc_middle[d85377d387f08e9a]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[f7d6eb8805e88c29]::plumbing::QueryCtxt, true>
  24:     0x7f70f05327d6 - rustc_query_impl[f7d6eb8805e88c29]::query_impl::mir_built::get_query_incr::__rust_end_short_backtrace
  25:     0x7f70f04bec30 - <rustc_mir_build[362e64e742f0429f]::check_unsafety::UnsafetyVisitor>::visit_inner_body
  26:     0x7f70eda7eed4 - <rustc_mir_build[362e64e742f0429f]::check_unsafety::UnsafetyVisitor as rustc_middle[d85377d387f08e9a]::thir::visit::Visitor>::visit_expr
  27:     0x7f70f04bed41 - <rustc_mir_build[362e64e742f0429f]::check_unsafety::UnsafetyVisitor>::visit_inner_body
  28:     0x7f70eda7eed4 - <rustc_mir_build[362e64e742f0429f]::check_unsafety::UnsafetyVisitor as rustc_middle[d85377d387f08e9a]::thir::visit::Visitor>::visit_expr
  29:     0x7f70f09c587e - <rustc_mir_build[362e64e742f0429f]::check_unsafety::UnsafetyVisitor as rustc_middle[d85377d387f08e9a]::thir::visit::Visitor>::visit_block
  30:     0x7f70eda801cd - <rustc_mir_build[362e64e742f0429f]::check_unsafety::UnsafetyVisitor as rustc_middle[d85377d387f08e9a]::thir::visit::Visitor>::visit_expr
  31:     0x7f70eda7eed4 - <rustc_mir_build[362e64e742f0429f]::check_unsafety::UnsafetyVisitor as rustc_middle[d85377d387f08e9a]::thir::visit::Visitor>::visit_expr
  32:     0x7f70f04bbe64 - rustc_mir_build[362e64e742f0429f]::check_unsafety::check_unsafety
  33:     0x7f70f04bb911 - rustc_query_impl[f7d6eb8805e88c29]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[f7d6eb8805e88c29]::query_impl::check_unsafety::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d85377d387f08e9a]::query::erase::Erased<[u8; 0usize]>>
  34:     0x7f70f053002a - rustc_query_system[bd604859ea317a95]::query::plumbing::try_execute_query::<rustc_query_impl[f7d6eb8805e88c29]::DynamicConfig<rustc_query_system[bd604859ea317a95]::query::caches::VecCache<rustc_span[86ddde2698e45e98]::def_id::LocalDefId, rustc_middle[d85377d387f08e9a]::query::erase::Erased<[u8; 0usize]>>, false, false, false>, rustc_query_impl[f7d6eb8805e88c29]::plumbing::QueryCtxt, true>
  35:     0x7f70f052fb37 - rustc_query_impl[f7d6eb8805e88c29]::query_impl::check_unsafety::get_query_incr::__rust_end_short_backtrace
  36:     0x7f70f05196ad - rustc_interface[45e847dd6c11ec07]::passes::analysis
  37:     0x7f70f0518787 - rustc_query_impl[f7d6eb8805e88c29]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[f7d6eb8805e88c29]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d85377d387f08e9a]::query::erase::Erased<[u8; 1usize]>>
  38:     0x7f70f107040a - rustc_query_system[bd604859ea317a95]::query::plumbing::try_execute_query::<rustc_query_impl[f7d6eb8805e88c29]::DynamicConfig<rustc_query_system[bd604859ea317a95]::query::caches::SingleCache<rustc_middle[d85377d387f08e9a]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[f7d6eb8805e88c29]::plumbing::QueryCtxt, true>
  39:     0x7f70f107001c - rustc_query_impl[f7d6eb8805e88c29]::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
  40:     0x7f70f0e270ce - rustc_interface[45e847dd6c11ec07]::interface::run_compiler::<core[e58631ecc326099b]::result::Result<(), rustc_span[86ddde2698e45e98]::ErrorGuaranteed>, rustc_driver_impl[3b65384176704029]::run_compiler::{closure#0}>::{closure#1}
  41:     0x7f70f0e126c9 - std[2409bda48c37ea6b]::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface[45e847dd6c11ec07]::util::run_in_thread_with_globals<rustc_interface[45e847dd6c11ec07]::util::run_in_thread_pool_with_globals<rustc_interface[45e847dd6c11ec07]::interface::run_compiler<core[e58631ecc326099b]::result::Result<(), rustc_span[86ddde2698e45e98]::ErrorGuaranteed>, rustc_driver_impl[3b65384176704029]::run_compiler::{closure#0}>::{closure#1}, core[e58631ecc326099b]::result::Result<(), rustc_span[86ddde2698e45e98]::ErrorGuaranteed>>::{closure#0}, core[e58631ecc326099b]::result::Result<(), rustc_span[86ddde2698e45e98]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[e58631ecc326099b]::result::Result<(), rustc_span[86ddde2698e45e98]::ErrorGuaranteed>>
  42:     0x7f70f0e12478 - <<std[2409bda48c37ea6b]::thread::Builder>::spawn_unchecked_<rustc_interface[45e847dd6c11ec07]::util::run_in_thread_with_globals<rustc_interface[45e847dd6c11ec07]::util::run_in_thread_pool_with_globals<rustc_interface[45e847dd6c11ec07]::interface::run_compiler<core[e58631ecc326099b]::result::Result<(), rustc_span[86ddde2698e45e98]::ErrorGuaranteed>, rustc_driver_impl[3b65384176704029]::run_compiler::{closure#0}>::{closure#1}, core[e58631ecc326099b]::result::Result<(), rustc_span[86ddde2698e45e98]::ErrorGuaranteed>>::{closure#0}, core[e58631ecc326099b]::result::Result<(), rustc_span[86ddde2698e45e98]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[e58631ecc326099b]::result::Result<(), rustc_span[86ddde2698e45e98]::ErrorGuaranteed>>::{closure#2} as core[e58631ecc326099b]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  43:     0x7f70ebd997bb - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h02edc3183d1b3ab4
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/alloc/src/boxed.rs:2022:9
  44:     0x7f70ebd997bb - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hd14ff6036f87e3a7
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/alloc/src/boxed.rs:2022:9
  45:     0x7f70ebd997bb - std::sys::pal::unix::thread::Thread::new::thread_start::he158ab2f3983310c
                               at /rustc/7d83a4c131ab9ae81a74c6fd825c827d74a2881d/library/std/src/sys/pal/unix/thread.rs:108:17
  46:     0x7f70ebb41ac3 - <unknown>
  47:     0x7f70ebbd3850 - <unknown>
  48:                0x0 - <unknown>
@bionicles bionicles 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 May 7, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 7, 2024
@compiler-errors compiler-errors added the F-async_closure `#![feature(async_closure)]` label May 7, 2024
@compiler-errors
Copy link
Member

I believe this is a duplicate of #124487, which I have a local branch to fix but which needs a bit of cleanup first.

@compiler-errors compiler-errors self-assigned this May 7, 2024
@bionicles bionicles changed the title Internal Compiler Error with awaited async closure within Poll Internal Compiler Error with awaited async closure within impl Future fn poll May 7, 2024
@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. F-async_closure `#![feature(async_closure)]` 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.
Projects
None yet
4 participants