Skip to content

repr(transparent) accepts too many types as ZST (repr_transparent_non_zst_fields, formerly repr_transparent_external_private_fields) #78586

Description

@scottmcm

View all comments

This tracks eventually removing support for repr(transparent) types ignoring ZST that might not actually remain ZST in the future or on other targets.

Types that can gain more fields

In crate A:

#[non_exhaustive]
pub struct UnitType {}

In crate B:

#[repr(transparent)]
pub struct TransparentThing(i32, UnitType);

I expected that to fail in crate B, because the reason crate A put #[non_exhaustive] on the type was to allow it to get additional fields in the future, which would no longer allow it to work in repr(transparent).

But this actually compiles today, creating what I would consider an accidental semver hazard.

https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Stability.20of.201-ZSTness/near/215120408


repr(C) types

#[repr(C)]
struct CZst([u8; 0]);

#[repr(transparent)]
pub struct TransparentThing(i32, CZst);

This should fail since CZst actually is not a ZST for all C compilers, and since the type can be relevant for the ABI.

Open questions

Activity

  1. added
    C-bugCategory: This is a bug.
    T-langRelevant to the language team
    on Oct 30, 2020
  2. Mark-Simulacrum commented on Oct 30, 2020

    @Mark-Simulacrum
    Member

    I'm going to nominate for lang, because I think (perhaps with a future compat lint) we should not look at foreign types' size unless that type is repr(transparent) for the purposes of checking here.

  3. added and removed on Oct 31, 2020
  4. scottmcm commented on Nov 2, 2020

    @scottmcm
    MemberAuthor

    Note that this also applies to the way this was done before non_exhaustive:

    pub struct UnitType(());
    

    As that private field also keeps others from constructing or exhaustively matching it, but it would still be accepted as 1-ZST by repr(transparent).

    We discussed this in the lang team meeting today. The consensus was that this is an accidental semver hazard that we'd like to do something about.

    @rustbot modify labels: +E-help-wanted +E-medium

    It'd be great to get a PR we could use to determine the impact of this. Ideally this isn't happening in the wild and can just be an error (maybe for one case or the other, if one is common and the other isn't) but it'll probably need at least a future imcompatibility lint.

  5. added
    E-help-wantedCall for participation: Help is requested to fix this issue.
    E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.
    on Nov 2, 2020
  6. jsomedon commented on Dec 6, 2020

    @jsomedon
    Contributor

    Hello folks, can I take this issue? I am kinda new to the community but I want to start contributing. :-)

  7. scottmcm commented on Dec 7, 2020

    @scottmcm
    MemberAuthor

    @jsomedon Absolutely! Unfortunately I don't really know the code here, so don't have suggestions for where to start, but you could always try tracing through the code around non_exhaustive and dropping by zulip if you run into any trouble.

  8. jsomedon commented on Dec 8, 2020

    @jsomedon
    Contributor

    Should a non-exhaustive struct be fine to stay in repr(transparent) in its own crate? (My understanding is that it's okay? As you can do whatever u want with the non-exhaustive in its own defining crate?)

  9. scottmcm commented on Dec 8, 2020

    @scottmcm
    MemberAuthor

    @jsomedon Yes, I think that's ok, like how one can exhaustively match it inside its own defining crate.

  10. horse-princess commented on Jan 23, 2021

    @horse-princess
    Contributor

    @jsomedon do you plan to continue working on this?

  11. 64 remaining items

  12. added 5 commits that reference this issue on Jun 11, 2026
  13. added a commit that references this issue on Jun 12, 2026
  14. added a commit that references this issue on Jun 12, 2026
  15. added a commit that references this issue on Oct 2, 2026
  16. added a commit that references this issue on Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-reprArea: the `#[repr(stuff)]` attributeC-future-incompatibilityCategory: Future-incompatibility lintsC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions