Rollup merge of #128934 - Nadrieril:fix-empty-non-exhaustive, r=compiler-errors
Non-exhaustive structs may be empty This is a follow-up to a discrepancy noticed in https://github.com/rust-lang/rust/pull/122792: today, the following struct is considered inhabited (non-empty) outside its defining crate: ```rust #[non_exhaustive] pub struct UninhabitedStruct { pub never: !, // other fields } ``` `#[non_exhaustive]` on a struct should mean that adding fields to it isn't a breaking change. There is no way that adding fields to this struct could make it non-empty since the `never` field must stay and is inconstructible. I suspect this was implemented this way due to confusion with `#[non_exhaustive]` enums, which indeed should be considered non-empty outside their defining crate. I propose that we consider such a struct uninhabited (empty), just like it would be without the `#[non_exhaustive]` annotation. Code that doesn't pass today and will pass after this: ```rust // In a different crate fn empty_match_on_empty_struct<T>(x: UninhabitedStruct) -> T { match x {} } ``` This is not a breaking change. r? ``@compiler-errors``
This commit is contained in:
commit
e7504ac704
16 changed files with 136 additions and 208 deletions
|
@ -81,10 +81,6 @@ impl<'tcx> VariantDef {
|
|||
adt: ty::AdtDef<'_>,
|
||||
) -> InhabitedPredicate<'tcx> {
|
||||
debug_assert!(!adt.is_union());
|
||||
if self.is_field_list_non_exhaustive() && !self.def_id.is_local() {
|
||||
// Non-exhaustive variants from other crates are always considered inhabited.
|
||||
return InhabitedPredicate::True;
|
||||
}
|
||||
InhabitedPredicate::all(
|
||||
tcx,
|
||||
self.fields.iter().map(|field| {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue