Skip to content

Commit ddcee6f

Browse files
committed
Modify FieldDef to allow parsing unnamed fields
1 parent ccf1712 commit ddcee6f

File tree

13 files changed

+246
-80
lines changed

13 files changed

+246
-80
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2471,19 +2471,39 @@ impl VisibilityKind {
24712471
}
24722472
}
24732473

2474+
/// Named field type
2475+
#[derive(Clone, Encodable, Decodable, Debug)]
2476+
pub struct NamedField {
2477+
// FIXME: Maybe remove option and use UnnamedField::Type instead of NamedField?
2478+
pub ident: Option<Ident>,
2479+
pub ty: P<Ty>,
2480+
}
2481+
2482+
/// Unnamed field type
2483+
#[derive(Clone, Encodable, Decodable, Debug)]
2484+
pub enum UnnamedField {
2485+
Struct(Vec<FieldDef>),
2486+
Union(Vec<FieldDef>),
2487+
Type(P<Ty>),
2488+
}
2489+
2490+
#[derive(Clone, Encodable, Decodable, Debug)]
2491+
pub enum FieldVariant {
2492+
Named(NamedField),
2493+
Unnamed(UnnamedField),
2494+
}
2495+
24742496
/// Field definition in a struct, variant or union.
24752497
///
24762498
/// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
24772499
#[derive(Clone, Encodable, Decodable, Debug)]
24782500
pub struct FieldDef {
24792501
pub attrs: Vec<Attribute>,
2480-
pub id: NodeId,
24812502
pub span: Span,
24822503
pub vis: Visibility,
2483-
pub ident: Option<Ident>,
2484-
2485-
pub ty: P<Ty>,
2504+
pub id: NodeId,
24862505
pub is_placeholder: bool,
2506+
pub variant: FieldVariant,
24872507
}
24882508

24892509
/// Fields and constructor ids of enum variants and structs.

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -909,13 +909,19 @@ pub fn noop_flat_map_field_def<T: MutVisitor>(
909909
mut fd: FieldDef,
910910
visitor: &mut T,
911911
) -> SmallVec<[FieldDef; 1]> {
912-
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd;
912+
let FieldDef { span, vis, id, attrs, is_placeholder: _, variant } = &mut fd;
913913
visitor.visit_span(span);
914-
visit_opt(ident, |ident| visitor.visit_ident(ident));
915914
visitor.visit_vis(vis);
916915
visitor.visit_id(id);
917-
visitor.visit_ty(ty);
918916
visit_attrs(attrs, visitor);
917+
match variant {
918+
FieldVariant::Named(NamedField { ident, ty }) => {
919+
visit_opt(ident, |ident| visitor.visit_ident(ident));
920+
visitor.visit_ty(ty);
921+
}
922+
// FIXME: Handle Unnamed variant
923+
_ => {}
924+
}
919925
smallvec![fd]
920926
}
921927

compiler/rustc_ast/src/visit.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -673,10 +673,16 @@ pub fn walk_struct_def<'a, V: Visitor<'a>>(visitor: &mut V, struct_definition: &
673673

674674
pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) {
675675
visitor.visit_vis(&field.vis);
676-
if let Some(ident) = field.ident {
677-
visitor.visit_ident(ident);
676+
match &field.variant {
677+
FieldVariant::Named(NamedField { ident, ty }) => {
678+
if let Some(ident) = ident {
679+
visitor.visit_ident(*ident);
680+
}
681+
visitor.visit_ty(&ty);
682+
}
683+
// FIXME: Handle Unnamed variant
684+
_ => {}
678685
}
679-
visitor.visit_ty(&field.ty);
680686
walk_list!(visitor, visit_attribute, &field.attrs);
681687
}
682688

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -792,31 +792,42 @@ impl<'hir> LoweringContext<'_, 'hir> {
792792
}
793793

794794
fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> {
795-
let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
796-
let t = self.lower_path_ty(
797-
&f.ty,
798-
qself,
799-
path,
800-
ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
801-
ImplTraitContext::disallowed(),
802-
);
803-
self.arena.alloc(t)
804-
} else {
805-
self.lower_ty(&f.ty, ImplTraitContext::disallowed())
806-
};
807795
let hir_id = self.lower_node_id(f.id);
796+
797+
let (ident, ty) = match &f.variant {
798+
FieldVariant::Named(NamedField { ident, ty }) => {
799+
let ident = match ident {
800+
Some(ident) => *ident,
801+
// FIXME(jseyfried): positional field hygiene.
802+
None => Ident::new(sym::integer(index), f.span),
803+
};
804+
805+
let ty = if let TyKind::Path(ref qself, ref path) = ty.kind {
806+
let t = self.lower_path_ty(
807+
ty,
808+
qself,
809+
path,
810+
ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
811+
ImplTraitContext::disallowed(),
812+
);
813+
self.arena.alloc(t)
814+
} else {
815+
self.lower_ty(&ty, ImplTraitContext::disallowed())
816+
};
817+
818+
(ident, ty)
819+
}
820+
// FIXME: Handle Unnamed variant. Currently creates useless data to pass the typecheck
821+
_ => {
822+
let ident = Ident::from_str_and_span("", f.span);
823+
let ty = self.arena.alloc(hir::Ty { hir_id, kind: hir::TyKind::Err, span: f.span });
824+
(ident, &*ty)
825+
}
826+
};
827+
808828
self.lower_attrs(hir_id, &f.attrs);
809-
hir::FieldDef {
810-
span: f.span,
811-
hir_id,
812-
ident: match f.ident {
813-
Some(ident) => ident,
814-
// FIXME(jseyfried): positional field hygiene.
815-
None => Ident::new(sym::integer(index), f.span),
816-
},
817-
vis: self.lower_visibility(&f.vis, None),
818-
ty,
819-
}
829+
830+
hir::FieldDef { span: f.span, hir_id, ident, vis: self.lower_visibility(&f.vis, None), ty }
820831
}
821832

822833
fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> {

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,7 +1408,13 @@ impl<'a> State<'a> {
14081408
s.maybe_print_comment(field.span.lo());
14091409
s.print_outer_attributes(&field.attrs);
14101410
s.print_visibility(&field.vis);
1411-
s.print_type(&field.ty)
1411+
match &field.variant {
1412+
ast::FieldVariant::Named(ast::NamedField { ident: _, ty }) => {
1413+
s.print_type(ty)
1414+
}
1415+
// FIXME: Handle Unnamed variant
1416+
_ => {}
1417+
}
14121418
});
14131419
self.pclose();
14141420
}
@@ -1430,10 +1436,15 @@ impl<'a> State<'a> {
14301436
self.maybe_print_comment(field.span.lo());
14311437
self.print_outer_attributes(&field.attrs);
14321438
self.print_visibility(&field.vis);
1433-
self.print_ident(field.ident.unwrap());
1434-
self.word_nbsp(":");
1435-
self.print_type(&field.ty);
1436-
self.s.word(",");
1439+
match &field.variant {
1440+
ast::FieldVariant::Named(ast::NamedField { ident, ty }) => {
1441+
self.print_ident(ident.unwrap());
1442+
self.word_nbsp(":");
1443+
self.print_type(ty);
1444+
self.s.word(",");
1445+
}
1446+
_ => {}
1447+
}
14371448
}
14381449

14391450
self.bclose(span)

compiler/rustc_builtin_macros/src/deriving/clone.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,13 @@ fn cs_clone_shallow(
127127
fn process_variant(cx: &mut ExtCtxt<'_>, stmts: &mut Vec<ast::Stmt>, variant: &VariantData) {
128128
for field in variant.fields() {
129129
// let _: AssertParamIsClone<FieldTy>;
130-
assert_ty_bounds(cx, stmts, field.ty.clone(), field.span, "AssertParamIsClone");
130+
match &field.variant {
131+
ast::FieldVariant::Named(ast::NamedField { ident: _, ty }) => {
132+
assert_ty_bounds(cx, stmts, ty.clone(), field.span, "AssertParamIsClone")
133+
}
134+
// FIXME: Handle Unnamed variant
135+
_ => {}
136+
}
131137
}
132138
}
133139

compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ fn cs_total_eq_assert(
7878
) {
7979
for field in variant.fields() {
8080
// let _: AssertParamIsEq<FieldTy>;
81-
assert_ty_bounds(cx, stmts, field.ty.clone(), field.span, "AssertParamIsEq");
81+
match &field.variant {
82+
ast::FieldVariant::Named(ast::NamedField { ident: _, ty }) => {
83+
assert_ty_bounds(cx, stmts, ty.clone(), field.span, "AssertParamIsEq")
84+
}
85+
// FIXME: Handle Unnamed variant
86+
_ => {}
87+
}
8288
}
8389
}
8490

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,15 @@ impl<'a> TraitDef<'a> {
720720
from_scratch: bool,
721721
use_temporaries: bool,
722722
) -> P<ast::Item> {
723-
let field_tys: Vec<P<ast::Ty>> =
724-
struct_def.fields().iter().map(|field| field.ty.clone()).collect();
723+
let field_tys: Vec<P<ast::Ty>> = struct_def
724+
.fields()
725+
.iter()
726+
.filter_map(|field| match &field.variant {
727+
ast::FieldVariant::Named(ast::NamedField { ident: _, ty }) => Some(ty.clone()),
728+
// FIXME: Handle Unnamed variant
729+
_ => None,
730+
})
731+
.collect();
725732

726733
let methods = self
727734
.methods
@@ -769,7 +776,13 @@ impl<'a> TraitDef<'a> {
769776
let mut field_tys = Vec::new();
770777

771778
for variant in &enum_def.variants {
772-
field_tys.extend(variant.data.fields().iter().map(|field| field.ty.clone()));
779+
field_tys.extend(variant.data.fields().iter().filter_map(
780+
|field| match &field.variant {
781+
ast::FieldVariant::Named(ast::NamedField { ident: _, ty }) => Some(ty.clone()),
782+
// FIXME: Handle Unnamed variant
783+
_ => None,
784+
},
785+
))
773786
}
774787

775788
let methods = self
@@ -1515,8 +1528,11 @@ impl<'a> TraitDef<'a> {
15151528
let mut just_spans = Vec::new();
15161529
for field in struct_def.fields() {
15171530
let sp = field.span.with_ctxt(self.span.ctxt());
1518-
match field.ident {
1519-
Some(ident) => named_idents.push((ident, sp)),
1531+
match field.variant {
1532+
ast::FieldVariant::Named(ast::NamedField { ident: Some(ident), ty: _ }) => {
1533+
named_idents.push((ident, sp))
1534+
}
1535+
// FIXME: Handle Unnamed variant
15201536
_ => just_spans.push(sp),
15211537
}
15221538
}
@@ -1576,7 +1592,13 @@ impl<'a> TraitDef<'a> {
15761592
let val = if use_temporaries { val } else { cx.expr_deref(sp, val) };
15771593
let val = cx.expr(sp, ast::ExprKind::Paren(val));
15781594

1579-
ident_exprs.push((sp, struct_field.ident, val, &struct_field.attrs[..]));
1595+
match struct_field.variant {
1596+
ast::FieldVariant::Named(ast::NamedField { ident, ty: _ }) => {
1597+
ident_exprs.push((sp, ident, val, &struct_field.attrs[..]))
1598+
}
1599+
// FIXME: Handle Unnamed variant
1600+
_ => {}
1601+
}
15801602
}
15811603

15821604
let subpats = self.create_subpatterns(cx, paths, mutbl, use_temporaries);

compiler/rustc_expand/src/expand.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,11 +328,15 @@ impl InvocationKind {
328328
// and it holds because only inert attributes are supported in this position.
329329
match self {
330330
InvocationKind::Attr { item: Annotatable::FieldDef(field), .. }
331-
| InvocationKind::Derive { item: Annotatable::FieldDef(field), .. }
332-
if field.ident.is_none() =>
331+
| InvocationKind::Derive { item: Annotatable::FieldDef(field), .. } => match field
332+
.variant
333333
{
334-
Some(field.vis.clone())
335-
}
334+
ast::FieldVariant::Named(ast::NamedField { ident, ty: _ }) if ident.is_none() => {
335+
Some(field.vis.clone())
336+
}
337+
// FIXME: Handle Unnamed variant
338+
_ => None,
339+
},
336340
_ => None,
337341
}
338342
}

compiler/rustc_expand/src/placeholders.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,12 @@ pub fn placeholder(
155155
}]),
156156
AstFragmentKind::StructFields => AstFragment::StructFields(smallvec![ast::FieldDef {
157157
attrs: Default::default(),
158-
id,
159-
ident: None,
160158
span,
161-
ty: ty(),
162159
vis,
160+
id,
163161
is_placeholder: true,
162+
// FIXME: Maybe change to UnnamedField?
163+
variant: ast::FieldVariant::Named(ast::NamedField { ident: None, ty: ty() })
164164
}]),
165165
AstFragmentKind::Variants => AstFragment::Variants(smallvec![ast::Variant {
166166
attrs: Default::default(),

0 commit comments

Comments
 (0)