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

Enums with only one variant and without #[repr(_)] have size 0 in 1.27 beta #50830

Closed
pietroalbini opened this issue May 17, 2018 · 12 comments
Closed
Labels
C-bug Category: This is a bug. regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Milestone

Comments

@pietroalbini
Copy link
Member

Some crates are defining enums with only one variant without using #[repr(_)], and in 1.27 beta those enums have size 0. This breaks those crates when they use transmute though.

An easy fix for those crates is adding the appropriate #[repr()] attribute to the enums, but we might want to revert the change to avoid breaking compatibility.

// Taken from libvirt-rpc in src/request.rs

#[derive(Debug)]
pub enum EventShutdownDetailType 
    Finished = 0,
}
@pietroalbini pietroalbini added the regression-from-stable-to-beta Performance or correctness regression from stable to beta. label May 17, 2018
@pietroalbini pietroalbini added this to the 1.27 milestone May 17, 2018
@pietroalbini pietroalbini added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels May 17, 2018
@hanna-kruppe
Copy link
Contributor

cc @nox

@nox
Copy link
Contributor

nox commented May 17, 2018

That was expected, I just don't think those transmute should be done in the first place. There is no guarantee that the enum has the size you expect it to have.

@pietroalbini
Copy link
Member Author

That transmute was allowed on stable though. Would it be possible to revert the 0-size if a number is attached to the variant? At the moment, A can't be transmuted, while B can:

pub enum A 
    Foo = 0,
}

pub enum B
    Foo = 0,
    Bar = 1,
}

@nox
Copy link
Contributor

nox commented May 17, 2018 via email

@eddyb
Copy link
Member

eddyb commented May 17, 2018

One such unsound transmute was the cause for one of the regressions from #45225, where an integer was transmuted to an enum even when it didn't match any of the enum variants, and that resulted in a crash elsewhere because the value was used as a niche.
I agree with @nox that catching these is good, but @rust-lang/compiler should take a look.

@eddyb
Copy link
Member

eddyb commented May 17, 2018

Also, all such problem can be fixed "locally", by adding a match or if-else chain and panicking if an incorrect value is given, without even changing the definition of the enum, at all.
So my suggestion would be to take each x.* and 0.y.* group of releases that contains the bad transmutes, yank them, and release one patch version for each, without the transmutes.

@nikomatsakis
Copy link
Contributor

@nikomatsakis
Copy link
Contributor

Discussed in the @rust-lang/compiler meeting at or around this point in the IRC log.

The current consensus is:

  • These transmutes were undefined behavior and hence we will not change the layout rules in response. The layout of enums is basically undefined.
  • However, it's clear that the layout rules and expectations are underdocumented. We should do two things to fix that:
    • clearer documentation in e.g. the rust reference (this is probably a matter for the Unsafe Code Guidelines team)
    • a more aggressive lint to identify transmutes that are not defined

Because these crates have no reverse dependencies, patching is relatively easy -- only new versions are needed. @polachok, @meqif, and @vinipsmaker: we would be very happy to help you rewrite the relevant code if needed! Let us know what help you may need!

@pietroalbini
Copy link
Member Author

Closing this as won't fix then.

@meqif
Copy link
Contributor

meqif commented May 17, 2018

I fully agree with the prevailing viewpoint that transmuting was undefined behavior, and that it really shouldn't be used.

In fact, this issue came up before and I fixed it in a later version of utp — I'm not sure why an older version of the crate was targeted here.

@pietroalbini
Copy link
Member Author

In fact, this issue came up before and I fixed it in a later version of utp — I'm not sure why an older version of the crate was targeted here.

Crater tests always the latest version of every crate, and also an older version for some of them.

@scottmcm
Copy link
Member

Note that previous changes have also "broken" UB transmutes, such as transmute::<[u8; 6], (u8,u16,u8)>, so this is a previously-decided category of allowed change.

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. regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants