rust-lang / rust

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

ICE: Broken MIR: NoSolution #120811

Open antiguru opened 7 months ago

antiguru commented 7 months ago

Code

Unfortunately it's nearly impossible for me to figure out where the problem actually happens, so finding a minimal example is tough.

Branch here: https://github.com/antiguru/timely-dataflow/tree/container_gat_ice

Command:

RUST_BACKTRACE=1 cargo check --features bincode --example wordcount_flatcontainer

Meta

rustc --version --verbose:

➜  timely-dataflow git:(container_gat_ice) rustc --version --verbose
rustc 1.76.0 (07dca489a 2024-02-04)
binary: rustc
commit-hash: 07dca489ac2d933c78d3c5158e3f43beefeb02ce
commit-date: 2024-02-04
host: x86_64-unknown-linux-gnu
release: 1.76.0
LLVM version: 17.0.6
➜

The same error happens on nightly.

Error output

warning: unnecessary `unsafe` block
  --> communication/src/allocator/zero_copy/push_pull.rs:93:26
   |
93 |             .map(|bytes| unsafe { Message::from_bytes(bytes) });
   |                          ^^^^^^ unnecessary `unsafe` block
   |
   = note: `#[warn(unused_unsafe)]` on by default

warning: unnecessary `unsafe` block
   --> communication/src/allocator/zero_copy/push_pull.rs:137:30
    |
137 |                 .map(|bytes| unsafe { Message::from_bytes(bytes) });
    |                              ^^^^^^ unnecessary `unsafe` block

warning: variant `Binary` is never constructed
  --> communication/src/message.rs:72:5
   |
70 | enum MessageContents<T> {
   |      --------------- variant in this enum
71 |     /// Binary representation. Only available as a reference.
72 |     Binary(abomonation::abomonated::Abomonated<T, Bytes>),
   |     ^^^^^^
   |
   = note: `#[warn(dead_code)]` on by default

warning: `timely_communication` (lib) generated 3 warnings
    Checking timely v0.12.0 (/home/moritz/dev/repos/timely-dataflow/timely)
warning: variable does not need to be mutable
  --> timely/examples/wordcount_flatcontainer.rs:44:37
   |
44 | ...                   for mut batch in val.drain(..) {
   |                           ----^^^^^
   |                           |
   |                           help: remove this `mut`
   |
   = note: `#[warn(unused_mut)]` on by default

error: internal compiler error: no errors encountered even though `span_delayed_bug` issued

error: internal compiler error: broken MIR in DefId(0:18 ~ wordcount_flatcontainer[7bab]::main::{closure#0}) ({closure@timely/examples/wordcount_flatcontainer.rs:22:38: 22:45} { input: move _10, exchange: move _5, probe: move _11 }): timely::dataflow::channels::pact::ExchangeCore<timely_container::flatcontainer::FlatStack<timely_container::flatcontainer::impls::tuple::TupleABRegion<timely_container::flatcontainer::StringRegion, timely_container::flatcontainer::MirrorRegion<i64>>>, Closure(DefId(0:19 ~ wordcount_flatcontainer[7bab]::main::{closure#0}::{closure#0}), [i16, Binder(extern "RustCall" fn((&ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) (&ReBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) str, i64),)) -> u64, [Region(BrAnon), Region(BrAnon)]), ()])> is not a subtype of timely::dataflow::channels::pact::ExchangeCore<timely_container::flatcontainer::FlatStack<timely_container::flatcontainer::impls::tuple::TupleABRegion<timely_container::flatcontainer::StringRegion, timely_container::flatcontainer::MirrorRegion<i64>>>, Closure(DefId(0:19 ~ wordcount_flatcontainer[7bab]::main::{closure#0}::{closure#0}), [i16, Binder(extern "RustCall" fn((&ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) Alias(Projection, AliasTy { args: [timely_container::flatcontainer::FlatStack<timely_container::flatcontainer::impls::tuple::TupleABRegion<timely_container::flatcontainer::StringRegion, timely_container::flatcontainer::MirrorRegion<i64>>>, ReBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon })], def_id: DefId(34:167 ~ timely_container[8ff9]::Container::Item) }),)) -> u64, [Region(BrAnon), Region(BrAnon)]), ()])>: NoSolution
  --> timely/examples/wordcount_flatcontainer.rs:22:38
   |
22 |           worker.dataflow::<usize,_,_>(|scope| {
   |  ______________________________________^
23 | |             input.to_stream(scope)
24 | |                  .flat_map::<FlatStack<<(String, i64) as Containerized>::Region>, _, _>(|(text, diff): (String, i64)|
25 | |                     text.split_whitespace()
...  |
57 | |                  .probe_with(&mut probe);
58 | |         });
   | |_________^
   |
note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:2440:17
         0: <rustc_errors::DiagCtxtInner>::emit_diagnostic_without_consuming
         1: <rustc_errors::DiagCtxtInner>::emit_diagnostic
         2: <rustc_errors::DiagCtxt>::span_delayed_bug::<rustc_span::span_encoding::Span, alloc::string::String>
         3: <rustc_borrowck::type_check::TypeChecker>::typeck_mir
         4: rustc_borrowck::type_check::type_check
         5: rustc_borrowck::nll::compute_regions
         6: rustc_borrowck::do_mir_borrowck
         7: rustc_borrowck::mir_borrowck
         8: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::mir_borrowck::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 8]>>
         9: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::VecCache<rustc_span::def_id::LocalDefId, rustc_middle::query::erase::Erased<[u8; 8]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, true>
        10: rustc_query_impl::query_impl::mir_borrowck::get_query_incr::__rust_end_short_backtrace
        11: <rustc_borrowck::type_check::TypeChecker>::prove_closure_bounds
        12: <rustc_borrowck::type_check::TypeChecker>::typeck_mir
        13: rustc_borrowck::type_check::type_check
        14: rustc_borrowck::nll::compute_regions
        15: rustc_borrowck::do_mir_borrowck
        16: rustc_borrowck::mir_borrowck
        17: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::mir_borrowck::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 8]>>
        18: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::VecCache<rustc_span::def_id::LocalDefId, rustc_middle::query::erase::Erased<[u8; 8]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, true>
        19: rustc_query_impl::query_impl::mir_borrowck::get_query_incr::__rust_end_short_backtrace
        20: rustc_interface::passes::analysis
        21: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 1]>>
        22: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::SingleCache<rustc_middle::query::erase::Erased<[u8; 1]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, true>
        23: rustc_query_impl::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
        24: rustc_interface::interface::run_compiler::<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}
        25: std::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface::util::run_in_thread_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>
        26: <<std::thread::Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
        27: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
                   at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/alloc/src/boxed.rs:2015:9
        28: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
                   at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/alloc/src/boxed.rs:2015:9
        29: std::sys::unix::thread::Thread::new::thread_start
                   at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/sys/unix/thread.rs:108:17
        30: start_thread
                   at ./nptl/pthread_create.c:444:8
        31: __GI___clone3
                   at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
  --> timely/examples/wordcount_flatcontainer.rs:22:38
   |
22 |           worker.dataflow::<usize,_,_>(|scope| {
   |  ______________________________________^
23 | |             input.to_stream(scope)
24 | |                  .flat_map::<FlatStack<<(String, i64) as Containerized>::Region>, _, _>(|(text, diff): (String, i64)|
25 | |                     text.split_whitespace()
...  |
57 | |                  .probe_with(&mut probe);
58 | |         });
   | |_________^

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.76.0 (07dca489a 2024-02-04) running on x86_64-unknown-linux-gnu

note: compiler flags: --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:
end of query stack
warning: `timely` (example "wordcount_flatcontainer") generated 1 warning (run `cargo fix --example "wordcount_flatcontainer"` to apply 1 suggestion)
error: could not compile `timely` (example "wordcount_flatcontainer"); 1 warning emitted
lqd commented 7 months ago

At least this is not a recent ICE: it already exists in 1.70.0, which is the oldest version supported by flatcontainer. From the stacktrace and that the example doesn't build without the bincode feature, it seems like an issue trying to emit diagnostics for errors encountered during MIR typechecking.

gurry commented 7 months ago

@rustbot claim

gurry commented 7 months ago

I tried minimizing using the following steps:

  1. Cloned https://github.com/antiguru/timely-dataflow/ and checked out branch container_gat_ice
  2. Installed treereduce-rust, opened a shell in the repo and ran this command to minimize: treereduce-rust -s timely/examples/wordcount_flatcontainer.rs --interesting-exit-code 101 -- cargo check --features bincode --example wordcount_flatcontainer

I was hoping it would minimize the file timely/examples/wordcount_flatcontainer.rs, but treereduce-rust seemed to get stuck forever. This is is the first time I'm using this tool and not sure I'm using it correctly. Any pointers will be appreciated. Maybe @matthiaskrgr can help.

matthiaskrgr commented 7 months ago

I have only every used treereduce on single files, together with `rustc file.rs' directly, not sure how it would work together with cargo (maybe try cargo-minimize?).

gurry commented 7 months ago

Thanks @matthiaskrgr. Appreciate the help.

cargo-minimize did work, but it being a simpler tool did not reduce in any meaningful way. Nonetheless, this does narrow the options down to only manual minimization which is what I'll try.

lqd commented 6 months ago

It was not easy to minimize but this GAT ICE is quite old, from nightly-2021-09-02.

trait Container {
    type Item<'a>;
}
impl Container for () {
    type Item<'a> = ();
}
struct Exchange<C, F> {
    _marker: std::marker::PhantomData<(C, F)>,
}
fn exchange<C, F>(_: F) -> Exchange<C, F>
where
    C: Container,
    for<'a> F: FnMut(&C::Item<'a>),
{
    unimplemented!()
}
trait Parallelization<C> {}
impl<C, F> Parallelization<C> for Exchange<C, F> {}
fn unary_frontier<P: Parallelization<()>>(_: P) {}
fn main() {
    let exchange = exchange(|_| ());
    let _ = || {
        unary_frontier(exchange);
    };
}