transmute: fix check for whether newtypes have equal size#155418
transmute: fix check for whether newtypes have equal size#155418RalfJung wants to merge 1 commit intorust-lang:mainfrom
Conversation
|
r? @JohnTitor rustbot has assigned @JohnTitor. Use Why was this reviewer chosen?The reviewer was selected based on:
|
| if int.is_some() | ||
| || align.is_some() | ||
| || pack.is_some() | ||
| || flags.difference(ReprFlags::IS_TRANSPARENT) != Default::default() |
There was a problem hiding this comment.
FWIW repr(C) is probably sometimes okay, but this code also handles enums with null pointer optimization and there repr(C) is definitely not okay.
|
@bors try |
This comment has been minimized.
This comment has been minimized.
transmute: fix check for whether newtypes have equal size
This comment has been minimized.
This comment has been minimized.
|
That's strange, I thought I had fixed this and it worked locally...
|
|
@RalfJung IIRC, the target that failed has Edit: Yup. #t-compiler/help > `Span` is 96 bits? |
|
Ah! There's a "randomize layout" flag. That should not affect crater though so we can go ahead and |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
f5db719 to
9d897cb
Compare
|
Actually, there's another flag we should ignore, and it's set on @craterbot abort |
This comment has been minimized.
This comment has been minimized.
transmute: fix check for whether newtypes have equal size
|
🗑️ Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
9d897cb to
c634619
Compare
|
@rustbot reroll |
|
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🎉 Experiment
Footnotes
|
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
Yeah that's entirely spurious. :) Nominating for team discussing. |
c634619 to
408547e
Compare
408547e to
ebc3514
Compare
There was a problem hiding this comment.
We seem to have absolutely no test for the NPO part of the transmute logic...
EDIT: except for a test recently added by @oli-obk , that I took the liberty to merge into this.
ebc3514 to
c16bd41
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
c16bd41 to
cb05096
Compare
cb05096 to
2a82bf1
Compare
|
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🎉 Experiment
Footnotes
|
View all comments
The
transmutecheck has some logic to be able to tell whether two types that involve generics will always have the same size. That logic has a bug: it ignores the fact thatrepr(align)can affect the size of a type. This PR fixes that bug by making the check bail out for mostreprflags. That rejects some previously accepted code, hence the @rust-lang/lang nomination.The new logic says that a type is a transparent newtype wrapper for
transmutepurposes only ifreprflags except forrepr(transparent).reprflags except forrepr(transparent)that matches the NPO rules. The inner type must benon_zero: true(which holds for references andNonNull), and the wrapper type is then marked asnon_zero: false.The new check is more conservative than it has to be. We do end up rejecting code like this:
We could refine the logic to understand that
repr(C)is fine here, but we have to be careful sincerepr(C)has to be taken into account by the null-pointer-optimization logic in thetransmutecheck. It seemed easier to just bail out onrepr(C)entirely, and crater found no regression.Fixes #155412
Fixes #88290
I manually checked that the playground example linked in #88290 now emits all three expected errors (and we have equivalent cases in the tests, either preexisting or added by this PR, so it didn't seem worth adding that example as well).