Skip to content

broken MIR in Item (nightly) #99866

Description

@ArthurKValladares

Code

#[derive(Debug)]
pub struct HalSetLayouts {
    vertex_layout: <B as hal::Backend>::DescriptorSetLayout,
    fragment_layout: <B as hal::Backend>::DescriptorSetLayout,
    fragment_sampler_layout: <B as hal::Backend>::DescriptorSetLayout,
}

impl HalSetLayouts {
    fn iter<DSL>(&self) -> impl ExactSizeIterator<Item = &DSL> + '_
    where
        // rust 1.37 fails to typecheck `iter` without this. This is fixed in nightly.
        B: hal::Backend<DescriptorSetLayout = DSL>,
        DSL: std::fmt::Debug + Send + Sync + 'static,
    {
        std::iter::once(&self.vertex_layout)
            .chain(std::iter::once(&self.fragment_layout))
            .chain(std::iter::once(&self.fragment_sampler_layout))
            .exact(3)
    }
}

Meta

rustc --version --verbose:

rustc 1.64.0-nightly (2643b1646 2022-07-27)
binary: rustc
commit-hash: 2643b16468fda787470340890212591d8bc832b7
commit-date: 2022-07-27
host: x86_64-apple-darwin
release: 1.64.0-nightly
LLVM version: 14.0.6

Error output

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

error: internal compiler error: broken MIR in Item(WithOptConstParam { did: DefId(0:3021 ~ renderer[c01e]::shader::{impl#11}::iter), const_param_did: None }) (end of phase transition to Optimized) at bb0[0]:
                                Field projection `(*_1).field[0]` specified type `DSL`, but actual type is <gfx_backend_metal::Backend as gfx_hal::Backend>::DescriptorSetLayout
   --> brainstorm/src/renderer/src/shader.rs:642:25
    |
642 |         std::iter::once(&self.vertex_layout)
    |                         ^^^^^^^^^^^^^^^^^^^
    |
    = note: delayed at compiler/rustc_const_eval/src/transform/validate.rs:129:36

error: internal compiler error: broken MIR in Item(WithOptConstParam { did: DefId(0:3021 ~ renderer[c01e]::shader::{impl#11}::iter), const_param_did: None }) (end of phase transition to Optimized) at bb1[0]:
                                Field projection `(*_1).field[1]` specified type `DSL`, but actual type is <gfx_backend_metal::Backend as gfx_hal::Backend>::DescriptorSetLayout
   --> brainstorm/src/renderer/src/shader.rs:643:36
    |
643 |             .chain(std::iter::once(&self.fragment_layout))
    |                                    ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: delayed at compiler/rustc_const_eval/src/transform/validate.rs:129:36

error: internal compiler error: broken MIR in Item(WithOptConstParam { did: DefId(0:3021 ~ renderer[c01e]::shader::{impl#11}::iter), const_param_did: None }) (end of phase transition to Optimized) at bb3[0]:
                                Field projection `(*_1).field[2]` specified type `DSL`, but actual type is <gfx_backend_metal::Backend as gfx_hal::Backend>::DescriptorSetLayout
   --> brainstorm/src/renderer/src/shader.rs:644:36
    |
644 |             .chain(std::iter::once(&self.fragment_sampler_layout))
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: delayed at compiler/rustc_const_eval/src/transform/validate.rs:129:36

Backtrace

thread 'rustc' panicked at 'Box<dyn Any>', compiler/rustc_errors/src/lib.rs:1426:13
stack backtrace:
   0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
   1: std::panic::panic_any::<rustc_errors::ExplicitBug>
   2: <rustc_errors::HandlerInner as core::ops::drop::Drop>::drop
   3: core::ptr::drop_in_place::<rustc_session::parse::ParseSess>
   4: <alloc::rc::Rc<rustc_session::session::Session> as core::ops::drop::Drop>::drop
   5: core::ptr::drop_in_place::<rustc_interface::interface::Compiler>
   6: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_interface::interface::create_compiler_and_run<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>::{closure#1}>
   7: rustc_interface::interface::create_compiler_and_run::<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>
   8: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, 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.

This came from a workaround for what seems to be an old compiler bug. removing the workaround gets ride of the ICE:

#[derive(Debug)]
pub struct HalSetLayouts {
    vertex_layout: <B as hal::Backend>::DescriptorSetLayout,
    fragment_layout: <B as hal::Backend>::DescriptorSetLayout,
    fragment_sampler_layout: <B as hal::Backend>::DescriptorSetLayout,
}

impl HalSetLayouts {
    fn iter(
        &self,
    ) -> impl ExactSizeIterator<Item = &<B as hal::Backend>::DescriptorSetLayout> + '_ {
        std::iter::once(&self.vertex_layout)
            .chain(std::iter::once(&self.fragment_layout))
            .chain(std::iter::once(&self.fragment_sampler_layout))
            .exact(3)
    }
}

Activity

  1. added
    C-bugCategory: This is a bug.
    I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jul 28, 2022
  2. ArthurKValladares commented on Jul 28, 2022

    @ArthurKValladares
    Author

    Of course, my bad for not providing this upfront. I've been able to repo it with this setup:

    deps/features:

    [features]
    default = ["metal"]
    dx12 = ["gfx-backend-dx12"]
    empty = ["gfx-backend-empty"]
    gl = ["gfx-backend-gl"]
    metal = ["gfx-backend-metal"]
    vulkan = ["gfx-backend-vulkan"]
    
    [dependencies]
    gfx-backend-dx12 = { version = "0.6.3", optional = true }
    gfx-backend-empty = { version = "0.6.0", optional = true }
    gfx-backend-gl = { version = "0.5.1", optional = true }
    gfx-backend-metal = { version = "0.6.2", optional = true }
    gfx-backend-vulkan = { version = "0.6.1", optional = true }
    gfx-hal = "0.6.0"
    

    lib.rs

    #[cfg(feature = "metal")]
    use gfx_backend_metal as back;
    pub use gfx_hal as hal;
    
    #[cfg(feature = "vulkan")]
    use gfx_backend_vulkan as back;
    
    #[cfg(not(any(feature = "metal", feature = "vulkan")))]
    use gfx_backend_empty as back;
    
    pub type B = back::Backend;
    
    pub struct Exacterator<I: Iterator<Item = T>, T> {
        iter: I,
        size: usize,
    }
    
    impl<I: Iterator<Item = T>, T> Exacterator<I, T> {
        pub fn new(iter: I, size: usize) -> Self {
            Self { iter, size }
        }
    }
    
    impl<I: Iterator<Item = T>, T> Iterator for Exacterator<I, T> {
        type Item = I::Item;
    
        fn next(&mut self) -> Option<Self::Item> {
            self.iter.next()
        }
    
        fn size_hint(&self) -> (usize, Option<usize>) {
            (self.size, Some(self.size))
        }
    }
    
    impl<I: Iterator<Item = T>, T> ExactSizeIterator for Exacterator<I, T> {}
    
    pub trait Exact<T>: Iterator<Item = T> + Sized {
        fn exact(self, size: usize) -> Exacterator<Self, T>;
    }
    
    impl<I: Iterator<Item = T>, T> Exact<T> for I {
        fn exact(self, size: usize) -> Exacterator<Self, T> {
            Exacterator::new(self, size)
        }
    }
    
    #[derive(Debug)]
    pub struct HalSetLayouts {
        vertex_layout: <B as hal::Backend>::DescriptorSetLayout,
        fragment_layout: <B as hal::Backend>::DescriptorSetLayout,
        fragment_sampler_layout: <B as hal::Backend>::DescriptorSetLayout,
    }
    
    impl HalSetLayouts {
        pub fn iter<DSL>(&self) -> impl ExactSizeIterator<Item = &DSL> + '_
        where
            // rust 1.37 fails to typecheck `iter` without this. This is fixed in nightly.
            B: hal::Backend<DescriptorSetLayout = DSL>,
            DSL: std::fmt::Debug + Send + Sync + 'static,
        {
            std::iter::once(&self.vertex_layout)
                .chain(std::iter::once(&self.fragment_layout))
                .chain(std::iter::once(&self.fragment_sampler_layout))
                .exact(3)
        }
    }
  3. Noratrieb commented on Jul 28, 2022

    @Noratrieb
    Member

    Here is the MIR for the iter function when I manually disabled validation (I just noticed, validation doesn't have to be disabled, -Zunpretty=mir works anyways)

    fn <impl at lol.rs:17:1: 17:19>::iter(_1: HalSetLayouts) -> DSL {
        debug self => _1;                    // in scope 0 at lol.rs:18:22: 18:26
        let mut _0: DSL;                     // return place in scope 0 at lol.rs:18:31: 18:34
    
        bb0: {
            _0 = move (_1.0: DSL);           // scope 0 at lol.rs:22:9: 22:27
            return;                          // scope 0 at lol.rs:23:6: 23:6
        }
    }
  4. Noratrieb commented on Jul 28, 2022

    @Noratrieb
    Member

    After looking into this a bit, I got the following:

    The body is treating the generic type DST and the concrete associated type <Back as Backend>::DescriptorSetLayout to be of the same type. The MIR validator probably thinks that this is very sketchy and bails out (I haven't looked at it closely).

    This is actually ok though, since in the where bounds DST is constrained to be equal to <Back as Backend>::DescriptorSetLayout.

    To me, this looks like a bug in the MIR validator.

  5. Noratrieb commented on Jul 28, 2022

    @Noratrieb
    Member

    This was probably regressed by #96856. cc @drmeepster

  6. Noratrieb commented on Jul 28, 2022

    @Noratrieb
    Member

    Yes, manually reverting the PR fixed the issue for me locally.

  7. Noratrieb commented on Jul 28, 2022

    @Noratrieb
    Member

    While it regressed in that PR, the PR only called validation that wasn't called before. The validation has been broken for longer.

  8. Noratrieb commented on Jul 29, 2022

    @Noratrieb
    Member

    @rustbot claim

  9. added a commit that references this issue on Jul 31, 2022
  10. 3 remaining items

  11. c410-f3r commented on Aug 26, 2022

    @c410-f3r
    Contributor

    Oooppsss... Sorry, this test still ICE.

    On the bright side, I was able to reduce the compiler arguments to --crate-type lib --emit=link.

  12. added 9 commits that reference this issue on Sep 1, 2022
    1ce0f18
    eea3f28
    b61c6d3
    a56e782
    6a3a886
    83d2870
    40bf492
    0d368cd
    34a430c
  13. added a commit that references this issue on Sep 2, 2022
    e5b9ec8
  14. added 2 commits that reference this issue on Sep 2, 2022
    3714928
    a67d5c0
  15. added a commit that references this issue on Sep 2, 2022
    938897e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

C-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions