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

Rust 1.20.0-nightly ICE with never_type: Broken MIR #43061

Closed
ngc0202 opened this issue Jul 5, 2017 · 4 comments · Fixed by #47746
Closed

Rust 1.20.0-nightly ICE with never_type: Broken MIR #43061

ngc0202 opened this issue Jul 5, 2017 · 4 comments · Fixed by #47746
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@ngc0202
Copy link

ngc0202 commented Jul 5, 2017

The following error results from dereferencing a *const ! as in this code: https://is.gd/SsSDiG

rustc 1.20.0-nightly (734c83642 2017-07-03)
error: internal compiler error: broken MIR (_3 = ()): bad assignment (! = ()): Sorts(ExpectedFound { expected: !, found: () })
 --> <anon>:4:5
  |
4 | /     unsafe {
5 | |         *x;
6 | |     }
  | |_____^

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

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.20.0-nightly (734c83642 2017-07-03) running on x86_64-unknown-linux-gnu

thread 'rustc' panicked at 'Box<Any>', /checkout/src/librustc_errors/lib.rs:426:8
@sfackler sfackler added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Jul 5, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@SimonSapin
Copy link
Contributor

What’s the correct fix? Compiler error with a nice error message?

@arielb1
Copy link
Contributor

arielb1 commented Nov 26, 2017

@SimonSapin

I think this should compile and UB, but a lint against this is probably a good idea.

@varkor
Copy link
Member

varkor commented Dec 31, 2017

Reduced test case:

// error: internal compiler error: broken MIR in NodeId(4) (_2 = ()):
//     bad assignment (! = ()): Sorts(ExpectedFound { expected: !, found: () })
#![crate_type = "lib"]
#![feature(never_type)]

fn blah(x: !) {
    x;
    // () // Uncommenting this explicit unit return avoids the ICE
}

@varkor
Copy link
Member

varkor commented Jan 9, 2018

I'm working on a fix for this. Progress on this branch. The idea is to avoid the typing issues entirely by terminating the blocks with unreachable as soon as a !-value is constructed. Currently the examples given here are fixed, but some more convoluted examples still crash.

bors added a commit that referenced this issue Jan 28, 2018
Fix never-type rvalue ICE

This fixes #43061.
r? @nikomatsakis

A small post-mortem as a follow-up to our investigations in #47291:
The problem as I understand it is that when `NeverToAny` coercions are made, the expression/statement that is coerced may be enclosed in a block. In our case, the statement `x;` was being transformed to something like: `NeverToAny( {x;} )`. Then, `NeverToAny` is transformed into an expression:
https://github.com/rust-lang/rust/blob/000fbbc9b8f88adc6a417f1caef41161f104250f/src/librustc_mir/build/expr/into.rs#L52-L59
Which ends up calling `ast_block_stmts` on the block `{x;}`, which triggers this condition:
https://github.com/rust-lang/rust/blob/000fbbc9b8f88adc6a417f1caef41161f104250f/src/librustc_mir/build/block.rs#L141-L147
In our case, there is no return expression, so `push_assign_unit` is called. But the block has already been recorded as _diverging_, meaning the result of the block will be assigned to a location of type `!`, rather than `()`. This causes the MIR error.
I'm assuming the `NeverToAny` coercion code is doing what it's supposed to (there don't seem to be any other problems), so fixing the issue simply consists of checking that the destination for the return value actually _is_ supposed to be a unit. (If no return value is given, the only other possible type for the return value is `!`, which can just be ignored, as it will be unreachable anyway.)

I checked the other cases of `push_assign_unit`, and it didn't look like they could be affected by the divergence issue (blocks are kind of special-cased in this regard as far as I can tell), so this should be sufficient to fix the issue.
bors added a commit that referenced this issue Mar 20, 2018
Eager unreachable blocks for `!` type

This change optimises the generation of MIR in the presence of `!`. Blocks are now immediately marked as unreachable if:
- A function argument is derived from the value of type `!`.
- A match arm binds a value whose type is derived from `!`.
- An rvalue is created whose type is derived from `!`.

This avoids unnecessary MIR generation and also fixes #43061 and #41446.

r? @nikomatsakis
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. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants