Skip to content

Commit 40465d2

Browse files
Remove anon struct and union types
1 parent e3a0da1 commit 40465d2

File tree

19 files changed

+3
-227
lines changed

19 files changed

+3
-227
lines changed

compiler/rustc_ast/src/ast.rs

-8
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

-4
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

-6
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

-3
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

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

compiler/rustc_ast_passes/messages.ftl

-4
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

compiler/rustc_ast_passes/src/ast_validation.rs

-17
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
}
@@ -293,15 +290,6 @@ impl<'a> AstValidator<'a> {
293290
}
294291
}
295292

296-
fn deny_anon_struct_or_union(&self, ty: &Ty) {
297-
let struct_or_union = match &ty.kind {
298-
TyKind::AnonStruct(..) => "struct",
299-
TyKind::AnonUnion(..) => "union",
300-
_ => return,
301-
};
302-
self.dcx().emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
303-
}
304-
305293
fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl) {
306294
let Const::Yes(span) = constness else {
307295
return;
@@ -865,14 +853,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
865853

866854
fn visit_ty(&mut self, ty: &'a Ty) {
867855
self.visit_ty_common(ty);
868-
self.deny_anon_struct_or_union(ty);
869856
self.walk_ty(ty)
870857
}
871858

872-
fn visit_field_def(&mut self, field: &'a FieldDef) {
873-
visit::walk_field_def(self, field)
874-
}
875-
876859
fn visit_item(&mut self, item: &'a Item) {
877860
if item.attrs.iter().any(|attr| attr.is_proc_macro_attr()) {
878861
self.has_proc_macro_decls = true;

compiler/rustc_ast_passes/src/errors.rs

-9
Original file line numberDiff line numberDiff line change
@@ -814,15 +814,6 @@ pub(crate) struct NegativeBoundWithParentheticalNotation {
814814
pub span: Span,
815815
}
816816

817-
#[derive(Diagnostic)]
818-
#[diag(ast_passes_anon_struct_or_union_not_allowed)]
819-
pub(crate) struct AnonStructOrUnionNotAllowed {
820-
#[primary_span]
821-
#[label]
822-
pub span: Span,
823-
pub struct_or_union: &'static str,
824-
}
825-
826817
#[derive(Diagnostic)]
827818
#[diag(ast_passes_match_arm_with_no_body)]
828819
pub(crate) struct MatchArmWithNoBody {

compiler/rustc_ast_pretty/src/pprust/state.rs

-8
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);

compiler/rustc_builtin_macros/src/deriving/clone.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ fn cs_clone_simple(
113113
// Already produced an assertion for this type.
114114
// Anonymous structs or unions must be eliminated as they cannot be
115115
// type parameters.
116-
} else if !field.ty.kind.is_anon_adt() {
116+
} else {
117117
// let _: AssertParamIsClone<FieldTy>;
118118
super::assert_ty_bounds(cx, &mut stmts, field.ty.clone(), field.span, &[
119119
sym::clone,

compiler/rustc_builtin_macros/src/deriving/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,6 @@ fn assert_ty_bounds(
124124
span: Span,
125125
assert_path: &[Symbol],
126126
) {
127-
// Deny anonymous structs or unions to avoid weird errors.
128-
assert!(!ty.kind.is_anon_adt(), "Anonymous structs or unions cannot be type parameters");
129127
// Generate statement `let _: assert_path<ty>;`.
130128
let span = cx.with_def_site_ctxt(span);
131129
let assert_path = cx.path_all(span, true, cx.std_path(assert_path), vec![GenericArg::Type(ty)]);

compiler/rustc_feature/src/removed.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ declare_features! (
217217
/// Allows using items which are missing stability attributes
218218
(removed, unmarked_api, "1.0.0", None, None),
219219
/// Allows unnamed fields of struct and union type
220-
(removed, unnamed_fields, "1.74.0", Some(49804)),
220+
(removed, unnamed_fields, "CURRENT_RUSTC_VERSION", Some(49804), Some("feature needs redesign")),
221221
(removed, unsafe_no_drop_flag, "1.0.0", None, None),
222222
/// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue.
223223
(removed, untagged_unions, "1.13.0", Some(55149),

compiler/rustc_parse/src/parser/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1984,7 +1984,7 @@ impl<'a> Parser<'a> {
19841984
}
19851985
}
19861986
self.expect_field_ty_separator()?;
1987-
let ty = self.parse_ty_for_field_def()?;
1987+
let ty = self.parse_ty()?;
19881988
if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) {
19891989
self.dcx().emit_err(errors::SingleColonStructType { span: self.token.span });
19901990
}

compiler/rustc_parse/src/parser/ty.rs

-47
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,6 @@ impl<'a> Parser<'a> {
128128
)
129129
}
130130

131-
/// Parse a type suitable for a field definition.
132-
/// The difference from `parse_ty` is that this version
133-
/// allows anonymous structs and unions.
134-
pub(super) fn parse_ty_for_field_def(&mut self) -> PResult<'a, P<Ty>> {
135-
if self.can_begin_anon_struct_or_union() {
136-
self.parse_anon_struct_or_union()
137-
} else {
138-
self.parse_ty()
139-
}
140-
}
141-
142131
/// Parse a type suitable for a function or function pointer parameter.
143132
/// The difference from `parse_ty` is that this version allows `...`
144133
/// (`CVarArgs`) at the top level of the type.
@@ -382,37 +371,6 @@ impl<'a> Parser<'a> {
382371
if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
383372
}
384373

385-
/// Parse an anonymous struct or union (only for field definitions):
386-
/// ```ignore (feature-not-ready)
387-
/// #[repr(C)]
388-
/// struct Foo {
389-
/// _: struct { // anonymous struct
390-
/// x: u32,
391-
/// y: f64,
392-
/// }
393-
/// _: union { // anonymous union
394-
/// z: u32,
395-
/// w: f64,
396-
/// }
397-
/// }
398-
/// ```
399-
fn parse_anon_struct_or_union(&mut self) -> PResult<'a, P<Ty>> {
400-
assert!(self.token.is_keyword(kw::Union) || self.token.is_keyword(kw::Struct));
401-
let is_union = self.token.is_keyword(kw::Union);
402-
403-
let lo = self.token.span;
404-
self.bump();
405-
406-
let (fields, _recovered) =
407-
self.parse_record_struct_body(if is_union { "union" } else { "struct" }, lo, false)?;
408-
let span = lo.to(self.prev_token.span);
409-
self.psess.gated_spans.gate(sym::unnamed_fields, span);
410-
let id = ast::DUMMY_NODE_ID;
411-
let kind =
412-
if is_union { TyKind::AnonUnion(id, fields) } else { TyKind::AnonStruct(id, fields) };
413-
Ok(self.mk_ty(span, kind))
414-
}
415-
416374
/// Parses either:
417375
/// - `(TYPE)`, a parenthesized type.
418376
/// - `(TYPE,)`, a tuple with a single field of type TYPE.
@@ -813,11 +771,6 @@ impl<'a> Parser<'a> {
813771
Ok(bounds)
814772
}
815773

816-
pub(super) fn can_begin_anon_struct_or_union(&mut self) -> bool {
817-
(self.token.is_keyword(kw::Struct) || self.token.is_keyword(kw::Union))
818-
&& self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace))
819-
}
820-
821774
/// Can the current token begin a bound?
822775
fn can_begin_bound(&mut self) -> bool {
823776
self.check_path()

compiler/rustc_passes/src/hir_stats.rs

-2
Original file line numberDiff line numberDiff line change
@@ -583,8 +583,6 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
583583
BareFn,
584584
Never,
585585
Tup,
586-
AnonStruct,
587-
AnonUnion,
588586
Path,
589587
Pat,
590588
TraitObject,

compiler/rustc_resolve/src/build_reduced_graph.rs

-23
Original file line numberDiff line numberDiff line change
@@ -724,29 +724,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
724724
// Record field names for error reporting.
725725
self.insert_field_idents(def_id, fields);
726726
self.insert_field_visibilities_local(def_id.to_def_id(), fields);
727-
728-
for field in fields {
729-
match &field.ty.kind {
730-
ast::TyKind::AnonStruct(id, nested_fields)
731-
| ast::TyKind::AnonUnion(id, nested_fields) => {
732-
let feed = self.r.feed(*id);
733-
let local_def_id = feed.key();
734-
let def_id = local_def_id.to_def_id();
735-
let def_kind = self.r.tcx.def_kind(local_def_id);
736-
let res = Res::Def(def_kind, def_id);
737-
self.build_reduced_graph_for_struct_variant(
738-
&nested_fields,
739-
Ident::empty(),
740-
feed,
741-
res,
742-
// Anonymous adts inherit visibility from their parent adts.
743-
adt_vis,
744-
field.ty.span,
745-
);
746-
}
747-
_ => {}
748-
}
749-
}
750727
}
751728

752729
/// Constructs the reduced graph for one item.

compiler/rustc_resolve/src/def_collector.rs

-18
Original file line numberDiff line numberDiff line change
@@ -105,22 +105,6 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
105105
let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name);
106106
let def = self.create_def(field.id, name, DefKind::Field, field.span);
107107
self.with_parent(def, |this| visit::walk_field_def(this, field));
108-
self.visit_anon_adt(&field.ty);
109-
}
110-
}
111-
112-
fn visit_anon_adt(&mut self, ty: &'a Ty) {
113-
let def_kind = match &ty.kind {
114-
TyKind::AnonStruct(..) => DefKind::Struct,
115-
TyKind::AnonUnion(..) => DefKind::Union,
116-
_ => return,
117-
};
118-
match &ty.kind {
119-
TyKind::AnonStruct(node_id, _) | TyKind::AnonUnion(node_id, _) => {
120-
let def_id = self.create_def(*node_id, kw::Empty, def_kind, ty.span);
121-
self.with_parent(def_id, |this| visit::walk_ty(this, ty));
122-
}
123-
_ => {}
124108
}
125109
}
126110

@@ -476,8 +460,6 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
476460
fn visit_ty(&mut self, ty: &'a Ty) {
477461
match &ty.kind {
478462
TyKind::MacCall(..) => self.visit_macro_invoc(ty.id),
479-
// Anonymous structs or unions are visited later after defined.
480-
TyKind::AnonStruct(..) | TyKind::AnonUnion(..) => {}
481463
TyKind::ImplTrait(id, _) => {
482464
// HACK: pprust breaks strings with newlines when the type
483465
// gets too long. We don't want these to show up in compiler

src/tools/rustfmt/src/types.rs

-2
Original file line numberDiff line numberDiff line change
@@ -951,8 +951,6 @@ impl Rewrite for ast::Ty {
951951
ast::TyKind::Tup(ref items) => {
952952
rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
953953
}
954-
ast::TyKind::AnonStruct(..) => Ok(context.snippet(self.span).to_owned()),
955-
ast::TyKind::AnonUnion(..) => Ok(context.snippet(self.span).to_owned()),
956954
ast::TyKind::Path(ref q_self, ref path) => {
957955
rewrite_path(context, PathContext::Type, q_self, path, shape)
958956
}

src/tools/rustfmt/tests/target/anonymous-types.rs

-31
This file was deleted.

0 commit comments

Comments
 (0)