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

broken MIR in Item (nightly) #99866

Closed
ArthurKValladares opened this issue Jul 28, 2022 · 13 comments · Fixed by #100121
Closed

broken MIR in Item (nightly) #99866

ArthurKValladares opened this issue Jul 28, 2022 · 13 comments · Fixed by #100121
Assignees
Labels
C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. 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

@ArthurKValladares
Copy link

ArthurKValladares commented Jul 28, 2022

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)
    }
}
@ArthurKValladares ArthurKValladares 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 Jul 28, 2022
@5225225
Copy link
Contributor

5225225 commented Jul 28, 2022

Can you post what your dependencies are? Or include the use statements? Ideally with the versions too.

Or something that can just be stuck in a main.rs that compiles? I'm not sure where the B is coming from in the code above (in the struct layout)

@ArthurKValladares
Copy link
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)
    }
}

@5225225
Copy link
Contributor

5225225 commented Jul 28, 2022

Ah yes, thank you very much. I can reproduce it (with the empty feature, so all the other crates can presumably be removed). I'll look into this.

@5225225
Copy link
Contributor

5225225 commented Jul 28, 2022

For reference, minimised it down to this:

pub trait Backend {
    type DescriptorSetLayout;
}

pub struct Back;

impl Backend for Back {
    type DescriptorSetLayout = u32;
}

pub struct HalSetLayouts {
    vertex_layout: <Back as Backend>::DescriptorSetLayout,
}

impl HalSetLayouts {
    pub fn iter<DSL>(self) -> DSL
    where
        Back: Backend<DescriptorSetLayout = DSL>,
    {
        self.vertex_layout
    }
}

I also bisected this, and it turns out to be the same rollup as in #99852... So I suspect both these errors were introduced in the same commit. Interesting!

Edit: Adjusted the code (edit2: twice!), check comment history for the original.

@Noratrieb
Copy link
Member

Noratrieb commented Jul 28, 2022

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
    }
}

@Noratrieb
Copy link
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.

@Noratrieb
Copy link
Member

This was probably regressed by #96856. cc @drmeepster

@Noratrieb
Copy link
Member

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

@Noratrieb
Copy link
Member

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

@Noratrieb
Copy link
Member

@rustbot claim

matthiaskrgr added a commit to matthiaskrgr/glacier that referenced this issue Jul 31, 2022
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Jul 31, 2022
@compiler-errors
Copy link
Member

Probably just needs a normalize call somewhere 🤔

@c410-f3r
Copy link
Contributor

Does not ICE any more after #100571. Test added in #100998.

@c410-f3r
Copy link
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.

Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 1, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc `@compiler-errors` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 1, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc ``@compiler-errors`` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 1, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc ```@compiler-errors``` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 1, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc ````@compiler-errors```` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 1, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc `````@compiler-errors````` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 2, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc `@compiler-errors` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 2, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc ``@compiler-errors`` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 2, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc ```@compiler-errors``` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 2, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc ````@compiler-errors```` who nicely helped me on zulip
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Sep 2, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc `````@compiler-errors````` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 2, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc ``````@compiler-errors`````` who nicely helped me on zulip
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Sep 2, 2022
… r=oli-obk

Try normalizing types without RevealAll in ParamEnv in MIR validation

Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

Fixes rust-lang#99866

cc ```````@compiler-errors``````` who nicely helped me on zulip
@bors bors closed this as completed in 938897e Sep 2, 2022
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. glacier ICE tracked in rust-lang/glacier. 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
6 participants