Skip to content

repr_transparent_external_private_fields lint fires on ManuallyDrop containing a ZST #129470

Closed

Description

Consider the following code:

struct ZST;

#[repr(transparent)]
struct TransparentWithManuallyDropZST {
    value: i32,
    md: std::mem::ManuallyDrop<ZST>,  // error: repr_transparent_external_private_fields
    zst: ZST,                         // no error
}

the field md fires a lint warning:

warning: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 --> src/lib.rs:7:5
  |
7 |     md: std::mem::ManuallyDrop<ZST>,
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
  = note: this struct contains `ManuallyDrop<ZST>`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future.
  = note: `#[warn(repr_transparent_external_private_fields)]` on by default

While the spirit of the lint seems reasonable, the docs state:

ManuallyDrop<T> is guaranteed to have the same layout and bit validity as T

So in this case, it seems like ManuallyDrop changing size would be a breaking change, and the lint at the very least misleading here. Perhaps an exclusion is needed on this lint for ManuallyDrop?


More generally, quoting the nomicon:

This repr is only considered part of the public ABI of a type if either the single field is pub, or if its layout is documented in prose. Otherwise, the layout should not be relied upon by other crates.

So, in ManuallyDrop's case, the single field is not pub, but the layout is documented in prose and so should be considered part of the ABI. Is it possible there are other types out there with such a layout guarantee in prose, which might also be incorrectly flagged by this lint?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-reprArea: the `#[repr(stuff)]` attributeL-repr_transparent_external_private_fieldsLint: repr_transparent_external_private_fieldsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions