rust-lang / rust

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

ICE on iterator closure with bevy advanced type alias #96488

Open nicopap opened 2 years ago

nicopap commented 2 years ago

Code

Sorry, I simply cannot create a minimal example, given it seems to result from an interaction with bevy's Query type and associated types (which is far from trivial to reproduce).

You'll get a link instead:

Please clone locally and run cargo check --package bevy_pbr.

The code in question is in crates/bevy_pbr/src/render/mesh.rs line 112 to 136.

The diff is reproduced here for your enjoyment:

diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs
index 2d227b85..34251ac3 100644
--- a/crates/bevy_pbr/src/render/mesh.rs
+++ b/crates/bevy_pbr/src/render/mesh.rs
@@ -128,7 +128,8 @@ pub fn extract_meshes(
     let is_visible = |(_, vis, ..): &ExtractMeshItem| vis.is_visible;
     let mut caster_cmds = Vec::with_capacity(*prev_len_caster);
     let mut not_caster_cmds = Vec::with_capacity(*prev_len_not);
-    caster_cmds.extend(caster_query.iter().filter(is_visible).map(mesh_bundle));
+    let bundle_visible = |item| is_visible(&item).then(|| mesh_bundle(item));
+    caster_cmds.extend(caster_query.iter().filter_map(bundle_visible));
     not_caster_cmds.extend(
         not_caster_query
             .iter()

I think the ICE comes from the typing of the is_visible and mesh_bundle closures, which has the input typed as ExtractMeshItem, which is defined as so:

pub type ExtractMeshQuery = (
    Entity,
    &'static ComputedVisibility,
    &'static GlobalTransform,
    &'static Handle<Mesh>,
    Option<&'static NotShadowReceiver>,
);
type ExtractMeshItem<'w, 's> = QueryItem<'w, 's, ExtractMeshQuery>;

QueryItem being itself a "simple" type alias:

pub type QueryItem<'w, 's, Q> = <<Q as WorldQuery>::Fetch as Fetch<'w, 's>>::Item;

Which everyone in the bevy community will tell you is a godsend.

Now, if I replace the definition of ExtractMeshItem as follow:

diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs
index 2d227b85..171b7a2d 100644
--- a/crates/bevy_pbr/src/render/mesh.rs
+++ b/crates/bevy_pbr/src/render/mesh.rs
@@ -101,7 +101,14 @@ pub type ExtractMeshQuery = (
     &'static Handle<Mesh>,
     Option<&'static NotShadowReceiver>,
 );
-type ExtractMeshItem<'w, 's> = QueryItem<'w, 's, ExtractMeshQuery>;
+type ExtractMeshItem<'w, 's> = (
+    Entity,
+    &'w ComputedVisibility,
+    &'w GlobalTransform,
+    &'w Handle<Mesh>,
+    Option<&'w NotShadowReceiver>,
+);

The code compiles as if nothing and the ICE is not triggered. Which is as close to a smoking gun you'll get here.

Meta

rustc --version --verbose:

rustc 1.60.0 (7737e0b5c 2022-04-04)
binary: rustc
commit-hash: 7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c
commit-date: 2022-04-04
host: x86_64-unknown-linux-gnu
release: 1.60.0
LLVM version: 14.0.0

Also tested with:

Error output

error: internal compiler error: broken MIR in DefId(0:1273 ~ bevy_pbr[909a]::render::mesh::extract_meshes::{closure#3}) ([closure@crates/bevy_pbr/src/render/me
sh.rs:128:57: 128:77] { mesh_bundle: move _9, item: move _10 }): &[closure@crates/bevy_pbr/src/render/mesh.rs:112:23: 125:6] is not a subtype of &[closure@crat
es/bevy_pbr/src/render/mesh.rs:112:23: 125:6]: NoSolution
   --> crates/bevy_pbr/src/render/mesh.rs:128:57
    |
128 |     let bundle_visibles = |item| is_visible(&item).then(|| mesh_bundle(item));
    |                                                         ^^^^^^^^^^^^^^^^^^^^
    |
    = note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:2467:17

error: internal compiler error: broken MIR in DefId(0:1269 ~ bevy_pbr[909a]::render::mesh::extract_meshes) ([closure@crates/bevy_pbr/src/render/mesh.rs:128:27:
 128:78] { is_visible: move _10, mesh_bundle: move _11 }): &[closure@crates/bevy_pbr/src/render/mesh.rs:127:22: 127:69] is not a subtype of &[closure@crates/be
vy_pbr/src/render/mesh.rs:127:22: 127:69]: NoSolution
   --> crates/bevy_pbr/src/render/mesh.rs:128:27
    |
128 |     let bundle_visibles = |item| is_visible(&item).then(|| mesh_bundle(item));
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:2467:17

error: internal compiler error: broken MIR in DefId(0:1269 ~ bevy_pbr[909a]::render::mesh::extract_meshes) ([closure@crates/bevy_pbr/src/render/mesh.rs:128:27:
 128:78] { is_visible: move _10, mesh_bundle: move _11 }): &[closure@crates/bevy_pbr/src/render/mesh.rs:112:23: 125:6] is not a subtype of &[closure@crates/bev
y_pbr/src/render/mesh.rs:112:23: 125:6]: NoSolution
   --> crates/bevy_pbr/src/render/mesh.rs:128:27
    |
128 |     let bundle_visibles = |item| is_visible(&item).then(|| mesh_bundle(item));
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:2467:17

note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

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.60.0 (7737e0b5c 2022-04-04) running on x86_64-unknown-linux-gnu

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

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

query stack during panic:
end of query stack
error: could not compile `bevy_pbr`
Backtrace

``` thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', compiler/rustc_errors/src/lib.rs:1176:13 stack backtrace: 0: rust_begin_unwind at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/panicking.rs:584:5 1: core::panicking::panic_fmt at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/panicking.rs:143:14 2: core::panicking::panic_display::<&str> 3: ::flush_delayed 4: ::drop 5: core::ptr::drop_in_place:: 6: as core::ops::drop::Drop>::drop 7: core::ptr::drop_in_place:: 8: rustc_interface::interface::create_compiler_and_run::, rustc_driver::run_compiler::{closure#1}> ``` bonus nightly backtrace: ``` thread 'rustc' panicked at 'Box', compiler/rustc_errors/src/lib.rs:1347:13 stack backtrace: 0: std::panicking::begin_panic:: 1: std::panic::panic_any:: 2: ::drop 3: core::ptr::drop_in_place:: 4: as core::ops::drop::Drop>::drop 5: core::ptr::drop_in_place:: 6: rustc_span::with_source_map::, rustc_interface::interface::create_compiler_and_run, rustc_driver::run_compiler::{closure#1}>::{closure#1}> 7: rustc_interface::interface::create_compiler_and_run::, rustc_driver::run_compiler::{closure#1}> 8: >::set::, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>> note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. ```

Enselic commented 7 months ago

Triage: Thank you for taking the time to report this. Can this still be reproduced? The reproducer does not necessarily need to be minimal, but it needs to be easy. In the spirit of "copy paste these bash commands". Otherwise the effort to look into this ICE will be too high compared to the hundreds of other ICE reports we have.