rust-lang / rust

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

ICE when using Matching, Async and Indexing #78366

Closed VincentWo closed 3 years ago

VincentWo commented 3 years ago

Code

enum Status {
    SystemOutage { issue_id: u32 },
}

#[tokio::main]
async fn main() {
    let issues: tokio::sync::RwLock<Vec<bool>> = Default::default();

    let closure = |status: Status| {
            async move {
                match status {
                    Status::SystemOutage { issue_id }
                        if issues.read().await[issue_id as usize] => {}
                    _ => {
                        // Do nothing;
                    }
                }
            }
        };
    closure(Status::SystemOutage { issue_id: 1 }).await;
}

Meta

rustc --version --verbose:

rustc 1.49.0-nightly (ffa2e7ae8 2020-10-24)
binary: rustc
commit-hash: ffa2e7ae8fbf9badc035740db949b9dae271c29f
commit-date: 2020-10-24
host: x86_64-unknown-linux-gnu
release: 1.49.0-nightly
LLVM version: 11.0

Error output

   Compiling system_change v0.1.0 (/home/perikles/programming/system_change_ice)
error: internal compiler error: compiler/rustc_mir/src/transform/generator.rs:751:13: Broken MIR: generator contains type &u32 in MIR, but typeck only knows about for<'r, 's, 't0> {ResumeTy, Status, u32, &'r tokio::sync::RwLock<Vec<bool>>, tokio::sync::RwLock<Vec<bool>>, impl std::future::Future, ()}
  --> src/main.rs:10:24
   |
10 |               async move {
   |  ________________________^
11 | |                 match status {
12 | |                     Status::SystemOutage { issue_id }
13 | |                         if issues.read().await[issue_id as usize] => {}
...  |
17 | |                 }
18 | |             }
   | |_____________^

thread 'rustc' panicked at 'Box<Any>', /rustc/ffa2e7ae8fbf9badc035740db949b9dae271c29f/compiler/rustc_errors/src/lib.rs:891:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

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

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

note: rustc 1.49.0-nightly (ffa2e7ae8 2020-10-24) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C debuginfo=2 -C incremental --crate-type bin

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

query stack during panic:
#0 [optimized_mir] optimizing MIR for `main::{closure#0}::{closure#0}::{closure#0}`
#1 [layout_raw] computing layout of `[static generator@src/main.rs:10:24: 18:14 for<'r, 's> {std::future::ResumeTy, Status, u32, &'r tokio::sync::RwLock<std::vec::Vec<bool>>, tokio::sync::RwLock<std::vec::Vec<bool>>, std::future::from_generator::GenFuture<[static generator@tokio::sync::RwLock::<T>::read::{closure#0} for<'t0, 't1> {std::future::ResumeTy, &'t0 tokio::sync::RwLock<std::vec::Vec<bool>>, u16, std::future::from_generator::GenFuture<[static generator@tokio::sync::rwlock::ReleasingPermit::<'a, T>::acquire::{closure#0} for<'t2, 't3, 't4> {std::future::ResumeTy, &'t2 tokio::sync::RwLock<std::vec::Vec<bool>>, u16, tokio::sync::RwLock<std::vec::Vec<bool>>, &'t3 tokio::sync::batch_semaphore::Semaphore, tokio::sync::batch_semaphore::Semaphore, u32, tokio::sync::batch_semaphore::Acquire<'t4>, ()}]>, ()}]>, ()}]`
end of query stack
error: aborting due to previous error

error: could not compile `system_change`

To learn more, run the command again with --verbose.
Backtrace

``` Compiling system_change v0.1.0 (/home/perikles/programming/system_change_ice) error: internal compiler error: compiler/rustc_mir/src/transform/generator.rs:751:13: Broken MIR: generator contains type &u32 in MIR, but typeck only knows about for<'r, 's, 't0> {ResumeTy, Status, u32, &'r tokio::sync::RwLock>, tokio::sync::RwLock>, impl std::future::Future, ()} --> src/main.rs:10:24 | 10 | async move { | ________________________^ 11 | | match status { 12 | | Status::SystemOutage { issue_id } 13 | | if issues.read().await[issue_id as usize] => {} ... | 17 | | } 18 | | } | |_____________^ thread 'rustc' panicked at 'Box', /rustc/ffa2e7ae8fbf9badc035740db949b9dae271c29f/compiler/rustc_errors/src/lib.rs:891:9 stack backtrace: 0: std::panicking::begin_panic 1: rustc_errors::HandlerInner::span_bug 2: rustc_errors::Handler::span_bug 3: rustc_middle::util::bug::opt_span_bug_fmt::{{closure}} 4: rustc_middle::ty::context::tls::with_opt::{{closure}} 5: rustc_middle::ty::context::tls::with_opt 6: rustc_middle::util::bug::opt_span_bug_fmt 7: rustc_middle::util::bug::span_bug_fmt 8: ::run_pass 9: rustc_mir::transform::run_passes 10: rustc_mir::transform::run_optimization_passes 11: rustc_mir::transform::optimized_mir 12: rustc_middle::dep_graph::::with_deps 13: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 14: rustc_data_structures::stack::ensure_sufficient_stack 15: rustc_query_system::query::plumbing::get_query_impl 16: rustc_middle::ty::layout::LayoutCx::layout_raw_uncached 17: rustc_middle::ty::layout::layout_raw 18: rustc_middle::ty::query:: for rustc_middle::ty::query::queries::layout_raw>::compute 19: rustc_middle::dep_graph::::with_deps 20: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 21: rustc_data_structures::stack::ensure_sufficient_stack 22: rustc_query_system::query::plumbing::get_query_impl 23: as rustc_target::abi::LayoutOf>::layout_of 24: as alloc::vec::SpecFromIter>::from_iter 25: as core::iter::traits::iterator::Iterator>::next 26: as alloc::vec::SpecFromIter>::from_iter 27: rustc_middle::ty::layout::LayoutCx::layout_raw_uncached 28: rustc_middle::ty::layout::layout_raw 29: rustc_middle::ty::query:: for rustc_middle::ty::query::queries::layout_raw>::compute 30: rustc_middle::dep_graph::::with_deps 31: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 32: rustc_data_structures::stack::ensure_sufficient_stack 33: rustc_query_system::query::plumbing::get_query_impl 34: as rustc_target::abi::LayoutOf>::layout_of 35: as alloc::vec::SpecFromIter>::from_iter 36: as core::iter::traits::iterator::Iterator>::next 37: as alloc::vec::SpecFromIter>::from_iter 38: rustc_middle::ty::layout::LayoutCx::layout_raw_uncached 39: rustc_middle::ty::layout::layout_raw 40: rustc_middle::ty::query:: for rustc_middle::ty::query::queries::layout_raw>::compute 41: rustc_middle::dep_graph::::with_deps 42: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 43: rustc_data_structures::stack::ensure_sufficient_stack 44: rustc_query_system::query::plumbing::get_query_impl 45: as rustc_target::abi::LayoutOf>::layout_of 46: as alloc::vec::SpecFromIter>::from_iter 47: as core::iter::traits::iterator::Iterator>::next 48: as alloc::vec::SpecFromIter>::from_iter 49: rustc_middle::ty::layout::LayoutCx::layout_raw_uncached 50: rustc_middle::ty::layout::layout_raw 51: rustc_middle::ty::query:: for rustc_middle::ty::query::queries::layout_raw>::compute 52: rustc_middle::dep_graph::::with_deps 53: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 54: rustc_data_structures::stack::ensure_sufficient_stack 55: rustc_query_system::query::plumbing::get_query_impl 56: as rustc_target::abi::LayoutOf>::layout_of 57: as core::iter::traits::iterator::Iterator>::try_fold 58: as core::iter::traits::iterator::Iterator>::try_fold 59: as alloc::vec::SpecFromIter>::from_iter 60: rustc_middle::ty::layout::LayoutCx::layout_raw_uncached 61: rustc_middle::ty::layout::layout_raw 62: rustc_middle::ty::query:: for rustc_middle::ty::query::queries::layout_raw>::compute 63: rustc_middle::dep_graph::::with_deps 64: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 65: rustc_data_structures::stack::ensure_sufficient_stack 66: rustc_query_system::query::plumbing::get_query_impl 67: as rustc_target::abi::LayoutOf>::layout_of 68: as alloc::vec::SpecFromIter>::from_iter 69: as core::iter::traits::iterator::Iterator>::next 70: as alloc::vec::SpecFromIter>::from_iter 71: rustc_middle::ty::layout::LayoutCx::layout_raw_uncached 72: rustc_middle::ty::layout::layout_raw 73: rustc_middle::ty::query:: for rustc_middle::ty::query::queries::layout_raw>::compute 74: rustc_middle::dep_graph::::with_deps 75: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 76: rustc_data_structures::stack::ensure_sufficient_stack 77: rustc_query_system::query::plumbing::get_query_impl 78: as rustc_target::abi::LayoutOf>::layout_of 79: ::run_pass 80: rustc_mir::transform::run_passes 81: rustc_mir::transform::run_optimization_passes 82: rustc_mir::transform::optimized_mir 83: rustc_middle::dep_graph::::with_deps 84: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 85: rustc_data_structures::stack::ensure_sufficient_stack 86: rustc_query_system::query::plumbing::get_query_impl 87: rustc_middle::ty::::instance_mir 88: rustc_mir::monomorphize::collector::collect_neighbours 89: rustc_mir::monomorphize::collector::collect_items_rec note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. note: the compiler unexpectedly panicked. this is a bug. 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 note: rustc 1.49.0-nightly (ffa2e7ae8 2020-10-24) running on x86_64-unknown-linux-gnu note: compiler flags: -C embed-bitcode=no -C debuginfo=2 -C incremental --crate-type bin note: some of the compiler flags provided by cargo are hidden query stack during panic: #0 [optimized_mir] optimizing MIR for `main::{closure#0}::{closure#0}::{closure#0}` #1 [layout_raw] computing layout of `[static generator@src/main.rs:10:24: 18:14 for<'r, 's> {std::future::ResumeTy, Status, u32, &'r tokio::sync::RwLock>, tokio::sync::RwLock>, std::future::from_generator::GenFuture<[static generator@tokio::sync::RwLock::::read::{closure#0} for<'t0, 't1> {std::future::ResumeTy, &'t0 tokio::sync::RwLock>, u16, std::future::from_generator::GenFuture<[static generator@tokio::sync::rwlock::ReleasingPermit::<'a, T>::acquire::{closure#0} for<'t2, 't3, 't4> {std::future::ResumeTy, &'t2 tokio::sync::RwLock>, u16, tokio::sync::RwLock>, &'t3 tokio::sync::batch_semaphore::Semaphore, tokio::sync::batch_semaphore::Semaphore, u32, tokio::sync::batch_semaphore::Acquire<'t4>, ()}]>, ()}]>, ()}]` #2 [layout_raw] computing layout of `std::future::from_generator::GenFuture<[static generator@src/main.rs:10:24: 18:14 for<'r, 's> {std::future::ResumeTy, Status, u32, &'r tokio::sync::RwLock>, tokio::sync::RwLock>, std::future::from_generator::GenFuture<[static generator@tokio::sync::RwLock::::read::{closure#0} for<'t0, 't1> {std::future::ResumeTy, &'t0 tokio::sync::RwLock>, u16, std::future::from_generator::GenFuture<[static generator@tokio::sync::rwlock::ReleasingPermit::<'a, T>::acquire::{closure#0} for<'t2, 't3, 't4> {std::future::ResumeTy, &'t2 tokio::sync::RwLock>, u16, tokio::sync::RwLock>, &'t3 tokio::sync::batch_semaphore::Semaphore, tokio::sync::batch_semaphore::Semaphore, u32, tokio::sync::batch_semaphore::Acquire<'t4>, ()}]>, ()}]>, ()}]>` #3 [layout_raw] computing layout of `std::mem::ManuallyDrop {std::future::ResumeTy, Status, u32, &'r tokio::sync::RwLock>, tokio::sync::RwLock>, std::future::from_generator::GenFuture<[static generator@tokio::sync::RwLock::::read::{closure#0} for<'t0, 't1> {std::future::ResumeTy, &'t0 tokio::sync::RwLock>, u16, std::future::from_generator::GenFuture<[static generator@tokio::sync::rwlock::ReleasingPermit::<'a, T>::acquire::{closure#0} for<'t2, 't3, 't4> {std::future::ResumeTy, &'t2 tokio::sync::RwLock>, u16, tokio::sync::RwLock>, &'t3 tokio::sync::batch_semaphore::Semaphore, tokio::sync::batch_semaphore::Semaphore, u32, tokio::sync::batch_semaphore::Acquire<'t4>, ()}]>, ()}]>, ()}]>>` #4 [layout_raw] computing layout of `std::mem::MaybeUninit {std::future::ResumeTy, Status, u32, &'r tokio::sync::RwLock>, tokio::sync::RwLock>, std::future::from_generator::GenFuture<[static generator@tokio::sync::RwLock::::read::{closure#0} for<'t0, 't1> {std::future::ResumeTy, &'t0 tokio::sync::RwLock>, u16, std::future::from_generator::GenFuture<[static generator@tokio::sync::rwlock::ReleasingPermit::<'a, T>::acquire::{closure#0} for<'t2, 't3, 't4> {std::future::ResumeTy, &'t2 tokio::sync::RwLock>, u16, tokio::sync::RwLock>, &'t3 tokio::sync::batch_semaphore::Semaphore, tokio::sync::batch_semaphore::Semaphore, u32, tokio::sync::batch_semaphore::Acquire<'t4>, ()}]>, ()}]>, ()}]>>` #5 [layout_raw] computing layout of `[static generator@src/main.rs:5:1: 5:15 {std::future::ResumeTy, tokio::sync::RwLock>, [closure@src/main.rs:9:19: 19:10], u32, Status, std::future::from_generator::GenFuture<[static generator@src/main.rs:10:24: 18:14 for<'r, 's> {std::future::ResumeTy, Status, u32, &'r tokio::sync::RwLock>, tokio::sync::RwLock>, std::future::from_generator::GenFuture<[static generator@tokio::sync::RwLock::::read::{closure#0} for<'t0, 't1> {std::future::ResumeTy, &'t0 tokio::sync::RwLock>, u16, std::future::from_generator::GenFuture<[static generator@tokio::sync::rwlock::ReleasingPermit::<'a, T>::acquire::{closure#0} for<'t2, 't3, 't4> {std::future::ResumeTy, &'t2 tokio::sync::RwLock>, u16, tokio::sync::RwLock>, &'t3 tokio::sync::batch_semaphore::Semaphore, tokio::sync::batch_semaphore::Semaphore, u32, tokio::sync::batch_semaphore::Acquire<'t4>, ()}]>, ()}]>, ()}]>, ()}]` #6 [layout_raw] computing layout of `std::future::from_generator::GenFuture<[static generator@src/main.rs:5:1: 5:15 {std::future::ResumeTy, tokio::sync::RwLock>, [closure@src/main.rs:9:19: 19:10], u32, Status, std::future::from_generator::GenFuture<[static generator@src/main.rs:10:24: 18:14 for<'r, 's> {std::future::ResumeTy, Status, u32, &'r tokio::sync::RwLock>, tokio::sync::RwLock>, std::future::from_generator::GenFuture<[static generator@tokio::sync::RwLock::::read::{closure#0} for<'t0, 't1> {std::future::ResumeTy, &'t0 tokio::sync::RwLock>, u16, std::future::from_generator::GenFuture<[static generator@tokio::sync::rwlock::ReleasingPermit::<'a, T>::acquire::{closure#0} for<'t2, 't3, 't4> {std::future::ResumeTy, &'t2 tokio::sync::RwLock>, u16, tokio::sync::RwLock>, &'t3 tokio::sync::batch_semaphore::Semaphore, tokio::sync::batch_semaphore::Semaphore, u32, tokio::sync::batch_semaphore::Acquire<'t4>, ()}]>, ()}]>, ()}]>, ()}]>` #7 [optimized_mir] optimizing MIR for `main` #8 [collect_and_partition_mono_items] collect_and_partition_mono_items end of query stack error: aborting due to previous error error: could not compile `system_change` To learn more, run the command again with --verbose. ```

This is the most minimal example I could find, it needs tokio with the features "macro" and "sync". While this error occured on Nightly I could also reproduce this on stable (as far back as on 1.39, didn't test beyond that because my build started failing because of other reasons)

SNCPlay42 commented 3 years ago

This is very reminiscent of #72651 (await in if guard in match statement)

SNCPlay42 commented 3 years ago

MCVE:

async fn bar() -> &'static [bool] {
    unimplemented!()
}

async fn foo(status: usize) {
    match status {
        x if bar().await[x] => {}
        _ => {}
    }
}

Yeah, very #72651.

VincentWo commented 3 years ago

Thank you for reducing this further. Totally forgot that I could just declare my own async function this way!

But I do understand correctly that the linked example is just related, not the same? (Since it's still occuring in latest nightly and the linked issue seemes to be already fixed)

SNCPlay42 commented 3 years ago

Yeah, just related - my immediate guess is this is some case that was missed in the fix for that issue. The difference appears to be that x is used in a index expression after the await instead of some other way.

SNCPlay42 commented 3 years ago

Another example:

async fn bar() -> usize {
    unimplemented!()
}

async fn foo(status: usize) {
    match status {
        x if bar().await == (x + 1) => {}
        _ => {}
    }
}

Any usage of x in the if guard after the await that does not cause x to be autorefed (like just == x from the #72651 MCVE would) appears to trigger the ICE.

SNCPlay42 commented 3 years ago

@rustbot claim

JohnTitor commented 3 years ago

Assigning P-high as discussed as part of the Prioritization Working Group procedure and removing I-prioritize.