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

ICE with match statement on a struct with const fn constructor #46114

Closed
GabrielMajeri opened this issue Nov 20, 2017 · 1 comment · Fixed by #46882
Closed

ICE with match statement on a struct with const fn constructor #46114

GabrielMajeri opened this issue Nov 20, 2017 · 1 comment · Fixed by #46882
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) C-bug Category: This is a bug.

Comments

@GabrielMajeri
Copy link
Contributor

GabrielMajeri commented Nov 20, 2017

Consider a simple struct which can be created at compile time (used in consts):

#[derive(Eq, PartialEq)]
struct A { value: u32 }

const fn new(value: u32) -> A {
  A { value }
}

I then defined some named constants:

const A_1: A = new(1);
const A_2: A = new(2);

Later on, I tried to use match to convert a variable of type A to a string:

let a_str = match a {
   A_1 => "A 1",
   A_2 => "A 2",
   _ => "Unknown A",
};

This leads to the following compiler crash:

error: internal compiler error: /checkout/src/librustc_const_eval/_match.rs:261: bad constructor ConstantValue(Const { ty: A, val: Aggregate(Struct([(value(91), Const { ty: u32, val: Integral(U32(1)) })])) }) for adt A

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.23.0-nightly (5041b3bb3 2017-11-19) running on x86_64-unknown-linux-gnu

thread 'rustc' panicked at 'Box<Any>', /checkout/src/librustc_errors/lib.rs:471:8
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Also uploaded the sample code to the Rust Playground.

As a side-note: it does not crash if I manually construct the structs, i.e.

const A_1: A = A { value: 1 };
const A_2: A = A { value: 2 };

Alternatively, it also works if I replace the match with if / else chains.

@TimNN TimNN added A-const-fn C-bug Category: This is a bug. labels Nov 21, 2017
bors added a commit that referenced this issue Jan 18, 2018
Replace all const evaluation with miri

* error reporting in constants prints a stacktrace through all called const fns
* Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level)
* can now use floating constants in patterns (previously only floating point literals were allowed)
    * the future compat lint is still produced for both cases
* can index into constant arrays during const eval (previously feature gated)
* can create a constant union value with field `a` and read from field `b`
* can dereference references into constants
* can create references inside constants (`const X: &u32 = &22`)
* Tuple struct constructors can be used in constants
* regression in const eval errors spans (some of these need improvements in mir debug info)
* can cast floats to ints and vice versa (in constants, and even nan/inf constants)
* Mir dump prints false/true instead of 0u8/1u8
* `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore.
    * Needs const propagation across projections
* `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I`
    * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not)

fixes #34997 (stack overflow with many constants)
fixes #25574 (deref byte strings in patterns)
fixes #27918 (broken mir ICE)
fixes #46114 (ICE on struct constructors in patterns)
fixes #37448 (`SomeStruct { foo } as SomeStruct`)
fixes #43754 (`return` in const fn)
fixes #41898 (tuple struct constructors)
fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit)
closes #29947 (const indexing stabilization)

r? @eddyb
@andreytkachenko
Copy link

I've also hit this bug

bors added a commit that referenced this issue Jan 30, 2018
Replace all const evaluation with miri

* error reporting in constants prints a stacktrace through all called const fns
* Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level)
* can now use floating constants in patterns (previously only floating point literals were allowed)
    * the future compat lint is still produced for both cases
* can index into constant arrays during const eval (previously feature gated)
* can create a constant union value with field `a` and read from field `b`
* can dereference references into constants
* can create references inside constants (`const X: &u32 = &22`)
* Tuple struct constructors can be used in constants
* regression in const eval errors spans (some of these need improvements in mir debug info)
* can cast floats to ints and vice versa (in constants, and even nan/inf constants)
* Mir dump prints false/true instead of 0u8/1u8
* `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore.
    * Needs const propagation across projections
* `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I`
    * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not)

fixes #34997 (stack overflow with many constants)
fixes #25574 (deref byte strings in patterns)
fixes #27918 (broken mir ICE)
fixes #46114 (ICE on struct constructors in patterns)
fixes #37448 (`SomeStruct { foo } as SomeStruct`)
fixes #43754 (`return` in const fn)
fixes #41898 (tuple struct constructors)
fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit)
closes #29947 (const indexing stabilization)
fixes #45044 (pattern matching repeat expressions)

r? @eddyb
bors added a commit that referenced this issue Feb 6, 2018
Replace all const evaluation with miri

* error reporting in constants prints a stacktrace through all called const fns
* Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level)
* can now use floating constants in patterns (previously only floating point literals were allowed)
    * the future compat lint is still produced for both cases
* can index into constant arrays during const eval (previously feature gated)
* can create a constant union value with field `a` and read from field `b`
* can dereference references into constants
* can create references inside constants (`const X: &u32 = &22`)
* Tuple struct constructors can be used in constants
* regression in const eval errors spans (some of these need improvements in mir debug info)
* can cast floats to ints and vice versa (in constants, and even nan/inf constants)
* Mir dump prints false/true instead of 0u8/1u8
* `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore.
    * Needs const propagation across projections
* `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I`
    * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not)
* can use `union`s to implement `transmute` for `Copy` types in constants without a feature gate. With all the greatness and nasal demons that come with this.

fixes #34997 (stack overflow with many constants)
fixes #25574 (deref byte strings in patterns)
fixes #27918 (broken mir ICE)
fixes #46114 (ICE on struct constructors in patterns)
fixes #37448 (`SomeStruct { foo } as SomeStruct`)
fixes #43754 (`return` in const fn)
fixes #41898 (tuple struct constructors)
fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit)
closes #29947 (const indexing stabilization)
fixes #45044 (pattern matching repeat expressions)
fixes #47971 (ICE on const fn + references)

r? @eddyb
bors added a commit that referenced this issue Mar 7, 2018
Replace all const evaluation with miri

* error reporting in constants prints a stacktrace through all called const fns
* Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level)
* can now use floating constants in patterns (previously only floating point literals were allowed)
    * the future compat lint is still produced for both cases
* can index into constant arrays during const eval (previously feature gated)
* can create a constant union value with field `a` and read from field `b`
* can dereference references into constants
* can create references inside constants (`const X: &u32 = &22`)
* Tuple struct constructors can be used in constants
* regression in const eval errors spans (some of these need improvements in mir debug info)
* can cast floats to ints and vice versa (in constants, and even nan/inf constants)
* Mir dump prints false/true instead of 0u8/1u8
* `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore.
    * Needs const propagation across projections
* `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I`
    * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not)
* can use `union`s to implement `transmute` for `Copy` types in constants without a feature gate. With all the greatness and nasal demons that come with this.
* can convert integers to `&'static T` in constants (useful for embedded)

fixes #34997 (stack overflow with many constants)
fixes #25574 (deref byte strings in patterns)
fixes #27918 (broken mir ICE)
fixes #46114 (ICE on struct constructors in patterns)
fixes #37448 (`SomeStruct { foo } as SomeStruct`)
fixes #43754 (`return` in const fn)
fixes #41898 (tuple struct constructors)
fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit)
closes #29947 (const indexing stabilization)
fixes #45044 (pattern matching repeat expressions)
fixes #47971 (ICE on const fn + references)
fixes #48081 (ICE on cyclic assoc const error)
fixes #48746 (nonhelpful error message with unions)

r? @eddyb

even though 1k loc are added in tests, this PR reduces the loc in this repository by 700
bors added a commit that referenced this issue Mar 8, 2018
Replace all const evaluation with miri

* error reporting in constants prints a stacktrace through all called const fns
* Trivial constant propagation and folding in MIR (always active, irrelevant of the optimization level)
* can now use floating constants in patterns (previously only floating point literals were allowed)
    * the future compat lint is still produced for both cases
* can index into constant arrays during const eval (previously feature gated)
* can create a constant union value with field `a` and read from field `b`
* can dereference references into constants
* can create references inside constants (`const X: &u32 = &22`)
* Tuple struct constructors can be used in constants
* regression in const eval errors spans (some of these need improvements in mir debug info)
* can cast floats to ints and vice versa (in constants, and even nan/inf constants)
* Mir dump prints false/true instead of 0u8/1u8
* `1i8 >> [8][0]` does not lint about exceeding bitshifts anymore.
    * Needs const propagation across projections
* `foo[I]` produces a const eval lint if `foo: [T; N]` and `N < I`
    * Essentially all builtin panics produce lints if they can be statically proven to trigger at runtime. This is on a best effort basis, so there might be some complex cases that don't trigger. (The runtime panic stays there, irrelevant of whether the lint is produced or not)
* can use `union`s to implement `transmute` for `Copy` types in constants without a feature gate. With all the greatness and nasal demons that come with this.
* can convert integers to `&'static T` in constants (useful for embedded)

fixes #34997 (stack overflow with many constants)
fixes #25574 (deref byte strings in patterns)
fixes #27918 (broken mir ICE)
fixes #46114 (ICE on struct constructors in patterns)
fixes #37448 (`SomeStruct { foo } as SomeStruct`)
fixes #43754 (`return` in const fn)
fixes #41898 (tuple struct constructors)
fixes #31364 (infinite recursion with const fn, fixed by miri's recursion limit)
closes #29947 (const indexing stabilization)
fixes #45044 (pattern matching repeat expressions)
fixes #47971 (ICE on const fn + references)
fixes #48081 (ICE on cyclic assoc const error)
fixes #48746 (nonhelpful error message with unions)

r? @eddyb

even though 1k loc are added in tests, this PR reduces the loc in this repository by 700
@RalfJung RalfJung added the A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) label Dec 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants