Rust: repr(transparent) should not consider non_exhaustive types as 1-ZSTs outside their crate

Created on 30 Oct 2020  路  2Comments  路  Source: rust-lang/rust

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

C-bug E-help-wanted E-medium T-lang

Most helpful comment

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.

All 2 comments

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.

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.

Was this page helpful?
0 / 5 - 0 ratings