Skip to content

transmute: fix check for whether newtypes have equal size#155418

Open
RalfJung wants to merge 1 commit intorust-lang:mainfrom
RalfJung:transmute-newtypes
Open

transmute: fix check for whether newtypes have equal size#155418
RalfJung wants to merge 1 commit intorust-lang:mainfrom
RalfJung:transmute-newtypes

Conversation

@RalfJung
Copy link
Copy Markdown
Member

@RalfJung RalfJung commented Apr 17, 2026

View all comments

The transmute check 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 that repr(align) can affect the size of a type. This PR fixes that bug by making the check bail out for most repr flags. 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 transmute purposes only if

  • It is a struct or single-variant enum without any repr flags except for repr(transparent).
  • Or it is a two-variant enum without any repr flags except for repr(transparent) that matches the NPO rules. The inner type must be non_zero: true (which holds for references and NonNull), and the wrapper type is then marked as non_zero: false.

The new check is more conservative than it has to be. We do end up rejecting code like this:

#[repr(C)]
pub struct Wrapper<T>(T);

pub fn foo<T: ?Sized>(x: *const T) -> Wrapper<*const T> {
  unsafe { std::mem::transmute::<*const T, Wrapper<*const T>>(x) }
}

We could refine the logic to understand that repr(C) is fine here, but we have to be careful since repr(C) has to be taken into account by the null-pointer-optimization logic in the transmute check. It seemed easier to just bail out on repr(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).

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 17, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 17, 2026

r? @JohnTitor

rustbot has assigned @JohnTitor.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler, types
  • compiler, types expanded to 72 candidates
  • Random selection from 18 candidates

@RalfJung RalfJung marked this pull request as draft April 17, 2026 06:59
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 17, 2026
Comment thread compiler/rustc_middle/src/ty/layout.rs Outdated
if int.is_some()
|| align.is_some()
|| pack.is_some()
|| flags.difference(ReprFlags::IS_TRANSPARENT) != Default::default()
Copy link
Copy Markdown
Member Author

@RalfJung RalfJung Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

View changes since the review

@RalfJung
Copy link
Copy Markdown
Member Author

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Apr 17, 2026
transmute: fix check for whether newtypes have equal size
@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Copy Markdown
Member Author

RalfJung commented Apr 17, 2026 via email

@theemathas
Copy link
Copy Markdown
Contributor

theemathas commented Apr 17, 2026

@RalfJung IIRC, the target that failed has -Zrandomize-layout turned on in CI.

Edit: Yup. #t-compiler/help > `Span` is 96 bits?

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Apr 17, 2026

☀️ Try build successful (CI)
Build commit: c9eed2c (c9eed2c4c04c13e48841f9c446608a7322ad16d5, parent: 0204aca0663ec534b773f78639b9ebe20b3da001)

@RalfJung
Copy link
Copy Markdown
Member Author

Ah! There's a "randomize layout" flag.

That should not affect crater though so we can go ahead and
@craterbot check

@craterbot
Copy link
Copy Markdown
Collaborator

👌 Experiment pr-155418 created and queued.
🤖 Automatically detected try build c9eed2c
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 17, 2026
@RalfJung RalfJung force-pushed the transmute-newtypes branch from f5db719 to 9d897cb Compare April 17, 2026 09:54
@RalfJung
Copy link
Copy Markdown
Member Author

Actually, there's another flag we should ignore, and it's set on Box, which could affect crater.

@craterbot abort
@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Apr 17, 2026
transmute: fix check for whether newtypes have equal size
@craterbot
Copy link
Copy Markdown
Collaborator

🗑️ Experiment pr-155418 deleted!

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Apr 17, 2026
@RalfJung RalfJung force-pushed the transmute-newtypes branch from 9d897cb to c634619 Compare April 17, 2026 10:31
@RalfJung RalfJung marked this pull request as ready for review April 17, 2026 10:31
@JohnTitor
Copy link
Copy Markdown
Member

@rustbot reroll

@rustbot rustbot assigned nikomatsakis and unassigned JohnTitor Apr 17, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Apr 17, 2026

☀️ Try build successful (CI)
Build commit: ad93f57 (ad93f57d532978d6739002a21bc66b45ed22f998, parent: 1b8f2e46e14b08208a53585570edd9206374aae8)

@RalfJung
Copy link
Copy Markdown
Member Author

@craterbot check

@craterbot
Copy link
Copy Markdown
Collaborator

👌 Experiment pr-155418 created and queued.
🤖 Automatically detected try build ad93f57
⚠️ Try build based on commit 9d897cb, but latest commit is c634619. Did you forget to make a new try build?
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 17, 2026
@craterbot
Copy link
Copy Markdown
Collaborator

🚧 Experiment pr-155418 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Copy Markdown
Collaborator

🎉 Experiment pr-155418 is completed!
📊 1 regressed and 3 fixed (896654 total)
📊 5288 spurious results on the retry-regressed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-155418/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels May 4, 2026
@RalfJung
Copy link
Copy Markdown
Member Author

RalfJung commented May 4, 2026

@craterbot
Copy link
Copy Markdown
Collaborator

👌 Experiment pr-155418-1 created and queued.
🤖 Automatically detected try build ad93f57
⚠️ Try build based on commit 9d897cb, but latest commit is c634619. Did you forget to make a new try build?
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 4, 2026
@RalfJung
Copy link
Copy Markdown
Member Author

RalfJung commented May 4, 2026

Yeah that's entirely spurious. :) Nominating for team discussing.

@RalfJung RalfJung added the I-lang-nominated Nominated for discussion during a lang team meeting. label May 4, 2026
@RalfJung RalfJung force-pushed the transmute-newtypes branch from c634619 to 408547e Compare May 4, 2026 07:35
@RalfJung RalfJung added the S-waiting-on-t-lang Status: Awaiting decision from T-lang label May 4, 2026
@RalfJung RalfJung force-pushed the transmute-newtypes branch from 408547e to ebc3514 Compare May 4, 2026 07:55
Comment on lines 36 to 38
Copy link
Copy Markdown
Member Author

@RalfJung RalfJung May 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread tests/ui/transmute/transmute-fat-pointers.rs Outdated
@RalfJung RalfJung force-pushed the transmute-newtypes branch from ebc3514 to c16bd41 Compare May 4, 2026 08:04
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 4, 2026

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.

@RalfJung RalfJung force-pushed the transmute-newtypes branch from c16bd41 to cb05096 Compare May 4, 2026 08:08
@RalfJung RalfJung force-pushed the transmute-newtypes branch from cb05096 to 2a82bf1 Compare May 4, 2026 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

I-lang-nominated Nominated for discussion during a lang team meeting. S-waiting-on-crater Status: Waiting on a crater run to be completed. S-waiting-on-t-lang Status: Awaiting decision from T-lang T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

transmute size check is wrong for overaligned newtype Transmute special-case doesn't take into consideration alignment or enum repr.

7 participants