1
Fork 0

Auto merge of #131045 - compiler-errors:remove-unnamed_fields, r=wesleywiser

Retire the `unnamed_fields` feature for now

`#![feature(unnamed_fields)]` was implemented in part in #115131 and #115367, however work on that feature has (afaict) stalled and in the mean time there have been some concerns raised (e.g.[^1][^2]) about whether `unnamed_fields` is worthwhile to have in the language, especially in its current desugaring. Because it represents a compiler implementation burden including a new kind of anonymous ADT and additional complication to field selection, and is quite prone to bugs today, I'm choosing to remove the feature.

However, since I'm not one to really write a bunch of words, I'm specifically *not* going to de-RFC this feature. This PR essentially *rolls back* the state of this feature to "RFC accepted but not yet implemented"; however if anyone wants to formally unapprove the RFC from the t-lang side, then please be my guest. I'm just not totally willing to summarize the various language-facing reasons for why this feature is or is not worthwhile, since I'm coming from the compiler side mostly.

Fixes #117942
Fixes #121161
Fixes #121263
Fixes #121299
Fixes #121722
Fixes #121799
Fixes #126969
Fixes #131041

Tracking:
* https://github.com/rust-lang/rust/issues/49804

[^1]: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Unnamed.20struct.2Funion.20fields
[^2]: https://github.com/rust-lang/rust/issues/49804#issuecomment-1972619108
This commit is contained in:
bors 2024-10-11 13:11:13 +00:00
commit f4966590d8
66 changed files with 32 additions and 3708 deletions

View file

@ -76,7 +76,6 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
check_transparent(tcx, def);
check_packed(tcx, span, def);
check_unnamed_fields(tcx, def);
}
fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
@ -86,61 +85,6 @@ fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
check_transparent(tcx, def);
check_union_fields(tcx, span, def_id);
check_packed(tcx, span, def);
check_unnamed_fields(tcx, def);
}
/// Check the representation of adts with unnamed fields.
fn check_unnamed_fields(tcx: TyCtxt<'_>, def: ty::AdtDef<'_>) {
if def.is_enum() {
return;
}
let variant = def.non_enum_variant();
if !variant.has_unnamed_fields() {
return;
}
if !def.is_anonymous() {
let adt_kind = def.descr();
let span = tcx.def_span(def.did());
let unnamed_fields = variant
.fields
.iter()
.filter(|f| f.is_unnamed())
.map(|f| {
let span = tcx.def_span(f.did);
errors::UnnamedFieldsReprFieldDefined { span }
})
.collect::<Vec<_>>();
debug_assert_ne!(unnamed_fields.len(), 0, "expect unnamed fields in this adt");
let adt_name = tcx.item_name(def.did());
if !def.repr().c() {
tcx.dcx().emit_err(errors::UnnamedFieldsRepr::MissingReprC {
span,
adt_kind,
adt_name,
unnamed_fields,
sugg_span: span.shrink_to_lo(),
});
}
}
for field in variant.fields.iter().filter(|f| f.is_unnamed()) {
let field_ty = tcx.type_of(field.did).instantiate_identity();
if let Some(adt) = field_ty.ty_adt_def()
&& !adt.is_enum()
{
if !adt.is_anonymous() && !adt.repr().c() {
let field_ty_span = tcx.def_span(adt.did());
tcx.dcx().emit_err(errors::UnnamedFieldsRepr::FieldMissingReprC {
span: tcx.def_span(field.did),
field_ty_span,
field_ty,
field_adt_kind: adt.descr(),
sugg_span: field_ty_span.shrink_to_lo(),
});
}
} else {
tcx.dcx().emit_err(errors::InvalidUnnamedFieldTy { span: tcx.def_span(field.did) });
}
}
}
/// Check that the fields of the `union` do not need dropping.