Repository navigation
Using a match statement on a field of an enum results in an internal compiler error #53728
Copy link
Copy link
Closed
Closed
Copy link
Labels
A-codegenArea: Code generationArea: Code generationI-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️P-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Description
Code
let packet = socket_sub.recv_bytes(0)?;
if let Some((info, data)) = decode_header(&packet) {
match info.device_kind {
_ => (),
}
}
Where info is
#[repr(C, packed)]
pub struct DeviceInfo {
pub uuid: [u8; 32],
pub endianness: u8,
pub device_io_caps: DeviceIo,
pub device_kind: DeviceKind,
pub device_id: u8,
}
and,
#[repr(u16)]
pub enum DeviceKind {
Nil = 0,
Unknown = 1,
}
Output
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `1`,
right: `0`', librustc_codegen_llvm/type_.rs:293:9
stack backtrace:
0: rust_metadata_std_3ed67ab4eddac0113ac194419553d62
1: rust_metadata_std_3ed67ab4eddac0113ac194419553d62
2: rust_metadata_std_3ed67ab4eddac0113ac194419553d62
3: rust_metadata_std_3ed67ab4eddac0113ac194419553d62
4: rust_metadata_rustc_8aa2fd7dd479240b1bd69b15bc880e38
5: std::panicking::rust_panic_with_hook
6: rust_metadata_std_3ed67ab4eddac0113ac194419553d62
7: std::panicking::begin_panic_fmt
8: rustc_codegen_llvm::type_::Type::padding_filler
9: <unknown>
10: <rustc_target::abi::TyLayout<'tcx, &'tcx rustc::ty::TyS<'tcx>> as rustc_codegen_llvm::type_of::LayoutLlvmExt<'tcx>>::llvm_type
11: <rustc_target::abi::call::FnType<'tcx, &'tcx rustc::ty::TyS<'tcx>> as rustc_codegen_llvm::abi::FnTypeExt<'a, 'tcx>>::llvm_type
12: <unknown>
13: rustc_codegen_llvm::mono_item::predefine_fn
14: <unknown>
15: rust_metadata_rustc_8aa2fd7dd479240b1bd69b15bc880e38
16: rust_metadata_rustc_8aa2fd7dd479240b1bd69b15bc880e38
17: rust_metadata_rustc_8aa2fd7dd479240b1bd69b15bc880e38
18: rust_metadata_rustc_8aa2fd7dd479240b1bd69b15bc880e38
19: rustc::ty::query::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::compile_codegen_unit
20: <unknown>
21: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_utils::codegen_backend::CodegenBackend>::codegen_crate
22: rustc_driver::driver::phase_4_codegen
23: <unknown>
24: <unknown>
25: rustc_driver::driver::compile_input
26: rustc_driver::run_compiler
27: <unknown>
28: __rust_maybe_catch_panic
29: <unknown>
30: rustc_driver::main
31: <unknown>
32: rust_metadata_std_3ed67ab4eddac0113ac194419553d62
33: __rust_maybe_catch_panic
34: std::rt::lang_start_internal
35: <unknown>
36: __libc_start_main
37: <unknown>
query stack during panic:
#0 [compile_codegen_unit] compile_codegen_unit
end of query stack
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/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.28.0 running on x86_64-unknown-linux-gnu
note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin
note: some of the compiler flags provided by cargo are hidden
Extra
I attempted to reproduce the logic in a simple example. However, the code compiled and ran properly.
The assertion failed here https://github.com/rust-lang/rust/blob/stable/src/librustc_codegen_llvm/type_.rs#L293
#[repr(u32)]
pub enum E1 {
Nil = 0,
Val = 1,
}
#[repr(u16)]
pub enum E2 {
Nil = 0,
Val = 1,
}
#[repr(C, packed)]
pub struct S {
pub a: [u8; 32],
pub b: u8,
pub c: E1,
pub d: E2,
pub e: u8,
}
fn main() {
let s = S {
a: [0; 32],
b: 0,
c: E1::Nil,
d: E2::Nil,
e: 42,
};
match s.d {
_ => (),
}
assert_eq!(std::mem::size_of::<S>(), 40);
}
Reactions are currently unavailable
Metadata
Metadata
Labels
A-codegenArea: Code generationArea: Code generationI-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️P-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Activity
estebank commentedon Aug 27, 2018
Can you provide access to the code causing the ICE? As you mention, the code in the ticket does not reproduce it. Also, could you try to compile the problematic code with the latest nightly?
vladglv commentedon Aug 27, 2018
I can reproduce the issue with the latest nightly (rustc 1.30.0-nightly (7219130 2018-08-26)).
vladglv commentedon Aug 27, 2018
Here is the code causing the ICE https://github.com/vladglv/bug-report .
sugar700 commentedon Aug 27, 2018
A minimal reproduction:
This regression was introduced in Rust 1.24.0, making it regression from stable to stable, the provided example works in Rust 1.23.0.
matthew-russo commentedon Aug 28, 2018
Was messing around a bit with different combinations to narrow down where it was. Very slightly more minimal
The repr(C) part is not necessary so figured I'd remove the noise.
Might be interesting to note --
None::<(DeviceInfo, u8)>;does not throw errorNone::<(DeviceInfo, u16)>;does throw errorAlso perhaps interesting to note: changing
DeviceKindtorepr(u8)removes all errors, but any higher than that (repr(u16),repr(u32),repr(u64), and their signed counterparts) all have errorspnkfelix commentedon Aug 30, 2018
tagging with T-compiler and P-high since it seems to qualify to be in those buckets
nikomatsakis commentedon Aug 30, 2018
Would be great to use https://github.com/rust-lang-nursery/cargo-bisect-rustc to try and narrow this down to at least a nightly if not a specific PR...
pnkfelix commentedon Aug 30, 2018
assigning to self to ensure that bisection gets done (by me or by anyone else who feels like posting the result of bisection here)
matthew-russo commentedon Aug 31, 2018
I tried running the bisection but don't know if I'm just doing it wrong or there is some other issue.
First I tried running from 1.23 to 1.24 and it says start has failed: Command I used:
output:
However when I build manually with
nightly-2017-10-31it works fineThen tried going by their relative commits and got a different error. Command I used:
output:
matthew-russo commentedon Sep 3, 2018
I've narrowed it down to be between nightly-2017-11-20 and nightly-2017-11-21. I have not locked down the exact commit but just looking at commit logs I'm assuming its this one f50fd07 as its a refactor of memory layouts. Will take a look in the next couple days.
pnkfelix commentedon Sep 4, 2018
Nota bene f50fd07 is from PR #45225
pnkfelix commentedon Sep 6, 2018
visited at rustc mtg. @arielb1 volunteered to do some more investigation.
eddyb commentedon Sep 6, 2018
So this is caused by the fact that
Option<(DeviceInfo, T)>uses a niche encoding, where the (misaligned/packed)DeviceKindat offset1is being used to encodeNone(with a tag value unused byDeviceKinditself), so its LLVM type needs to be equivalent to this:But that second
_filler1tries to use an integer with the same alignment asT, which fails because the misalignment/packing needs it to be of a size that's not a multiple of that.I'll try to open a PR soon.
EDIT: oops it's actually
_filler0(it doesn't get past that). It appears that the struct/enum alignment is considered to possibly be less than field alignment, but not individual offsets to be misaligned.EDIT2: this assert could've fired but it doesn't here because
offsetis0:rust/src/librustc_codegen_llvm/type_of.rs
Line 137 in 35a5541
EDIT3: this additional assertion does get triggered, if I add it:
Rollup merge of rust-lang#53998 - eddyb:issue-53728, r=oli-obk
Auto merge of #53998 - eddyb:issue-53728, r=oli-obk