Skip to content

Commit f496659

Browse files
committed
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: * #49804 [^1]: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Unnamed.20struct.2Funion.20fields [^2]: #49804 (comment)
2 parents 484c8e7 + 6628bba commit f496659

File tree

66 files changed

+32
-3708
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+32
-3708
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,10 +2167,6 @@ pub enum TyKind {
21672167
Never,
21682168
/// A tuple (`(A, B, C, D,...)`).
21692169
Tup(ThinVec<P<Ty>>),
2170-
/// An anonymous struct type i.e. `struct { foo: Type }`.
2171-
AnonStruct(NodeId, ThinVec<FieldDef>),
2172-
/// An anonymous union type i.e. `union { bar: Type }`.
2173-
AnonUnion(NodeId, ThinVec<FieldDef>),
21742170
/// A path (`module::module::...::Type`), optionally
21752171
/// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
21762172
///
@@ -2227,10 +2223,6 @@ impl TyKind {
22272223
None
22282224
}
22292225
}
2230-
2231-
pub fn is_anon_adt(&self) -> bool {
2232-
matches!(self, TyKind::AnonStruct(..) | TyKind::AnonUnion(..))
2233-
}
22342226
}
22352227

22362228
/// Syntax used to declare a trait object.

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -519,10 +519,6 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
519519
visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Impl));
520520
}
521521
TyKind::MacCall(mac) => vis.visit_mac_call(mac),
522-
TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => {
523-
vis.visit_id(id);
524-
fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
525-
}
526522
}
527523
visit_lazy_tts(vis, tokens);
528524
vis.visit_span(span);

compiler/rustc_ast/src/util/classify.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,6 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
287287
| ast::TyKind::Pat(..)
288288
| ast::TyKind::Dummy
289289
| ast::TyKind::Err(..) => break None,
290-
291-
// These end in brace, but cannot occur in a let-else statement.
292-
// They are only parsed as fields of a data structure. For the
293-
// purpose of denying trailing braces in the expression of a
294-
// let-else, we can disregard these.
295-
ast::TyKind::AnonStruct(..) | ast::TyKind::AnonUnion(..) => break None,
296290
}
297291
}
298292
}

compiler/rustc_ast/src/visit.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,9 +535,6 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
535535
TyKind::Err(_guar) => {}
536536
TyKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
537537
TyKind::Never | TyKind::CVarArgs => {}
538-
TyKind::AnonStruct(_id, ref fields) | TyKind::AnonUnion(_id, ref fields) => {
539-
walk_list!(visitor, visit_field_def, fields);
540-
}
541538
}
542539
V::Result::output()
543540
}

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,46 +1259,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12591259
let kind = match &t.kind {
12601260
TyKind::Infer => hir::TyKind::Infer,
12611261
TyKind::Err(guar) => hir::TyKind::Err(*guar),
1262-
// Lower the anonymous structs or unions in a nested lowering context.
1263-
//
1264-
// ```
1265-
// struct Foo {
1266-
// _: union {
1267-
// // ^__________________ <-- within the nested lowering context,
1268-
// /* fields */ // | we lower all fields defined into an
1269-
// } // | owner node of struct or union item
1270-
// // ^_____________________|
1271-
// }
1272-
// ```
1273-
TyKind::AnonStruct(node_id, fields) | TyKind::AnonUnion(node_id, fields) => {
1274-
// Here its `def_id` is created in `build_reduced_graph`.
1275-
let def_id = self.local_def_id(*node_id);
1276-
debug!(?def_id);
1277-
let owner_id = hir::OwnerId { def_id };
1278-
self.with_hir_id_owner(*node_id, |this| {
1279-
let fields = this.arena.alloc_from_iter(
1280-
fields.iter().enumerate().map(|f| this.lower_field_def(f)),
1281-
);
1282-
let span = t.span;
1283-
let variant_data =
1284-
hir::VariantData::Struct { fields, recovered: ast::Recovered::No };
1285-
// FIXME: capture the generics from the outer adt.
1286-
let generics = hir::Generics::empty();
1287-
let kind = match t.kind {
1288-
TyKind::AnonStruct(..) => hir::ItemKind::Struct(variant_data, generics),
1289-
TyKind::AnonUnion(..) => hir::ItemKind::Union(variant_data, generics),
1290-
_ => unreachable!(),
1291-
};
1292-
hir::OwnerNode::Item(this.arena.alloc(hir::Item {
1293-
ident: Ident::new(kw::Empty, span),
1294-
owner_id,
1295-
kind,
1296-
span: this.lower_span(span),
1297-
vis_span: this.lower_span(span.shrink_to_lo()),
1298-
}))
1299-
});
1300-
hir::TyKind::AnonAdt(hir::ItemId { owner_id })
1301-
}
13021262
TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
13031263
TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
13041264
TyKind::Ref(region, mt) => {

compiler/rustc_ast_passes/messages.ftl

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
ast_passes_anon_struct_or_union_not_allowed =
2-
anonymous {$struct_or_union}s are not allowed outside of unnamed struct or union fields
3-
.label = anonymous {$struct_or_union} declared here
4-
51
ast_passes_assoc_const_without_body =
62
associated constant in `impl` without body
73
.suggestion = provide a definition for the constant
@@ -160,14 +156,6 @@ ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation}
160156
.type = inherent impl for this type
161157
.only_trait = only trait implementations may be annotated with {$annotation}
162158
163-
ast_passes_invalid_unnamed_field =
164-
unnamed fields are not allowed outside of structs or unions
165-
.label = unnamed field declared here
166-
167-
ast_passes_invalid_unnamed_field_ty =
168-
unnamed fields can only have struct or union types
169-
.label = not a struct or union
170-
171159
ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot be declared with `safe` safety qualifier
172160
.suggestion = remove safe from this item
173161

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,6 @@ impl<'a> AstValidator<'a> {
244244
}
245245
}
246246
}
247-
TyKind::AnonStruct(_, ref fields) | TyKind::AnonUnion(_, ref fields) => {
248-
walk_list!(self, visit_struct_field_def, fields)
249-
}
250247
_ => visit::walk_ty(self, t),
251248
}
252249
}
@@ -255,7 +252,6 @@ impl<'a> AstValidator<'a> {
255252
if let Some(ident) = field.ident
256253
&& ident.name == kw::Underscore
257254
{
258-
self.check_unnamed_field_ty(&field.ty, ident.span);
259255
self.visit_vis(&field.vis);
260256
self.visit_ident(ident);
261257
self.visit_ty_common(&field.ty);
@@ -294,39 +290,6 @@ impl<'a> AstValidator<'a> {
294290
}
295291
}
296292

297-
fn check_unnamed_field_ty(&self, ty: &Ty, span: Span) {
298-
if matches!(
299-
&ty.kind,
300-
// We already checked for `kw::Underscore` before calling this function,
301-
// so skip the check
302-
TyKind::AnonStruct(..) | TyKind::AnonUnion(..)
303-
// If the anonymous field contains a Path as type, we can't determine
304-
// if the path is a valid struct or union, so skip the check
305-
| TyKind::Path(..)
306-
) {
307-
return;
308-
}
309-
self.dcx().emit_err(errors::InvalidUnnamedFieldTy { span, ty_span: ty.span });
310-
}
311-
312-
fn deny_anon_struct_or_union(&self, ty: &Ty) {
313-
let struct_or_union = match &ty.kind {
314-
TyKind::AnonStruct(..) => "struct",
315-
TyKind::AnonUnion(..) => "union",
316-
_ => return,
317-
};
318-
self.dcx().emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
319-
}
320-
321-
fn deny_unnamed_field(&self, field: &FieldDef) {
322-
if let Some(ident) = field.ident
323-
&& ident.name == kw::Underscore
324-
{
325-
self.dcx()
326-
.emit_err(errors::InvalidUnnamedField { span: field.span, ident_span: ident.span });
327-
}
328-
}
329-
330293
fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl) {
331294
let Const::Yes(span) = constness else {
332295
return;
@@ -890,15 +853,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
890853

891854
fn visit_ty(&mut self, ty: &'a Ty) {
892855
self.visit_ty_common(ty);
893-
self.deny_anon_struct_or_union(ty);
894856
self.walk_ty(ty)
895857
}
896858

897-
fn visit_field_def(&mut self, field: &'a FieldDef) {
898-
self.deny_unnamed_field(field);
899-
visit::walk_field_def(self, field)
900-
}
901-
902859
fn visit_item(&mut self, item: &'a Item) {
903860
if item.attrs.iter().any(|attr| attr.is_proc_macro_attr()) {
904861
self.has_proc_macro_decls = true;

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -814,33 +814,6 @@ pub(crate) struct NegativeBoundWithParentheticalNotation {
814814
pub span: Span,
815815
}
816816

817-
#[derive(Diagnostic)]
818-
#[diag(ast_passes_invalid_unnamed_field_ty)]
819-
pub(crate) struct InvalidUnnamedFieldTy {
820-
#[primary_span]
821-
pub span: Span,
822-
#[label]
823-
pub ty_span: Span,
824-
}
825-
826-
#[derive(Diagnostic)]
827-
#[diag(ast_passes_invalid_unnamed_field)]
828-
pub(crate) struct InvalidUnnamedField {
829-
#[primary_span]
830-
pub span: Span,
831-
#[label]
832-
pub ident_span: Span,
833-
}
834-
835-
#[derive(Diagnostic)]
836-
#[diag(ast_passes_anon_struct_or_union_not_allowed)]
837-
pub(crate) struct AnonStructOrUnionNotAllowed {
838-
#[primary_span]
839-
#[label]
840-
pub span: Span,
841-
pub struct_or_union: &'static str,
842-
}
843-
844817
#[derive(Diagnostic)]
845818
#[diag(ast_passes_match_arm_with_no_body)]
846819
pub(crate) struct MatchArmWithNoBody {

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
541541
gate_all!(builtin_syntax, "`builtin #` syntax is unstable");
542542
gate_all!(explicit_tail_calls, "`become` expression is experimental");
543543
gate_all!(generic_const_items, "generic const items are experimental");
544-
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
545544
gate_all!(fn_delegation, "functions delegation is not yet fully implemented");
546545
gate_all!(postfix_match, "postfix match is experimental");
547546
gate_all!(mut_ref, "mutable by-reference bindings are experimental");

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,14 +1174,6 @@ impl<'a> State<'a> {
11741174
}
11751175
self.pclose();
11761176
}
1177-
ast::TyKind::AnonStruct(_, fields) => {
1178-
self.head("struct");
1179-
self.print_record_struct_body(fields, ty.span);
1180-
}
1181-
ast::TyKind::AnonUnion(_, fields) => {
1182-
self.head("union");
1183-
self.print_record_struct_body(fields, ty.span);
1184-
}
11851177
ast::TyKind::Paren(typ) => {
11861178
self.popen();
11871179
self.print_type(typ);

0 commit comments

Comments
 (0)