-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Open
Labels
A-reprArea: the `#[repr(stuff)]` attributeArea: the `#[repr(stuff)]` attributeC-bugCategory: This is a bug.Category: This is a bug.T-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.T-opsemRelevant to the opsem teamRelevant to the opsem team
Description
Uninhabited repr(C) enums are size zero, not the size of their discriminant. For instance:
enum Never {}
#[repr(C, u64)]
enum E {
_X(Never),
_Y(Never),
}
fn main (){
use core::mem::size_of;
let never_size = size_of::<Never>();
assert_eq!(0, never_size);
let disr_size = size_of::<u64>();
assert_eq!(8, disr_size);
let expected_enum_size = disr_size + never_size;
let actual_enum_size = size_of::<E>();
assert_eq!(expected_enum_size, actual_enum_size); // FAIL! 8 != 0
}At best, this leads to nonsensical errors. For instance, this:
enum Never {}
#[repr(C, u64)]
enum E {
_X(Never),
_Y(E),
}error[E0072]: recursive type `E` has infinite size
--> src/lib.rs:4:1
|
4 | enum E {
| ^^^^^^ recursive type has infinite size
5 | _X(Never),
6 | _Y(E),
| - recursive without indirection
|
= help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `E` representable
At worst, it violates the specification of RFC2195: Really Tagged Unions, which dictates that E should be layout-compatible to the union of its variants:
use core::mem::size_of;
#[derive(Copy, Clone)]
enum Never {}
// This:
#[repr(C, u64)]
enum E {
_X(Never),
_Y(Never),
}
// ...should have the same layout as `ERepr`:
#[derive(Copy, Clone)]
#[repr(C)]
union ERepr {
A: EX,
B: EY,
}
type ETag = u64;
#[derive(Copy, Clone)] struct EX(ETag, Never);
#[derive(Copy, Clone)] struct EY(ETag, Never);
// ...but it doesn't:
fn main() {
assert_eq!(size_of::<E>(), size_of::<ERepr>()); // FAIL: 0 != 8
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-reprArea: the `#[repr(stuff)]` attributeArea: the `#[repr(stuff)]` attributeC-bugCategory: This is a bug.Category: This is a bug.T-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.T-opsemRelevant to the opsem teamRelevant to the opsem team
Type
Fields
Give feedbackNo fields configured for issues without a type.