-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-coercionsArea: implicit and explicit `expr as Type` coercionsArea: implicit and explicit `expr as Type` coercionsC-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-langRelevant to the language teamRelevant to the language team
Description
I tried this code:
#[repr(u8)]
pub enum FooBar {
Foo(i32),
Bar(String),
}
impl FooBar {
fn discriminant(&self) -> u8 {
unsafe { *(self as *const Self as *const u8) }
}
}
fn main() {
println!("{}", FooBar::Foo as u8);
println!("{}", FooBar::Bar as u8);
println!("{}", FooBar::Foo(42).discriminant());
println!("{}", FooBar::Bar("baz".to_owned()).discriminant());
}
I expected to see this happen: The code should fail to compile, as casting to u8 for this enum is not allowed.
Instead, this happened: code compiles fine, and prints garbage. The garbage printed appears to be part of the address of the function that would instantiate the respective variant of the enum. As there are no warnings issued, this can be very nasty. Clippy does detect this and correctly warns.
Playground for easy reproduction on any compiler of choice.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3e3b23e01f545caf4f4fc88ab45edd61
Note
- Making any one field not contain any value will make this fail to compile (which is the expected result)
- This can be especially nasty if you have an enum with no payload in any of the fields (which is safe to cast) and then add payload to all of the fields. The code will still compile, even though its meaning has changed completely.
Metadata
Metadata
Assignees
Labels
A-coercionsArea: implicit and explicit `expr as Type` coercionsArea: implicit and explicit `expr as Type` coercionsC-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-langRelevant to the language teamRelevant to the language team