Skip to content

Commit 727c7c7

Browse files
committed
rustc: Add stub support for struct variants to the AST
1 parent bc267c6 commit 727c7c7

File tree

14 files changed

+237
-144
lines changed

14 files changed

+237
-144
lines changed

src/libsyntax/ast.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,13 @@ type foreign_mod =
632632
type variant_arg = {ty: @ty, id: node_id};
633633

634634
#[auto_serialize]
635-
type variant_ = {name: ident, attrs: ~[attribute], args: ~[variant_arg],
635+
enum variant_kind {
636+
tuple_variant_kind(~[variant_arg]),
637+
struct_variant_kind
638+
}
639+
640+
#[auto_serialize]
641+
type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind,
636642
id: node_id, disr_expr: option<@expr>, vis: visibility};
637643

638644
#[auto_serialize]

src/libsyntax/ast_util.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,13 @@ fn is_exported(i: ident, m: _mod) -> bool {
187187
for m.items.each |it| {
188188
if it.ident == i { local = true; }
189189
match it.node {
190-
item_enum(variants, _) => for variants.each |v| {
191-
if v.node.name == i {
192-
local = true;
193-
parent_enum = some(/* FIXME (#2543) */ copy it.ident);
190+
item_enum(variants, _) =>
191+
for variants.each |v| {
192+
if v.node.name == i {
193+
local = true;
194+
parent_enum = some(/* FIXME (#2543) */ copy it.ident);
195+
}
194196
}
195-
},
196197
_ => ()
197198
}
198199
if local { break; }

src/libsyntax/ext/auto_serialize.rs

Lines changed: 69 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -830,43 +830,51 @@ fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: ast::ident,
830830
let variant = variants[vidx];
831831
let v_span = variant.span;
832832
let v_name = variant.node.name;
833-
let variant_tys = vec::map(variant.node.args, |a| a.ty);
834-
835-
ser_variant(
836-
cx, tps, variant_tys, v_span, cx.clone(s),
837-
838-
// Generate pattern var(v1, v2, v3)
839-
|pats| {
840-
if vec::is_empty(pats) {
841-
ast::pat_ident(ast::bind_by_implicit_ref,
842-
cx.path(v_span, ~[v_name]),
843-
none)
844-
} else {
845-
ast::pat_enum(cx.path(v_span, ~[v_name]), some(pats))
846-
}
847-
},
848-
849-
// Generate body s.emit_enum_variant("foo", 0u,
850-
// 3u, {|| blk })
851-
|-s, blk| {
852-
let v_name = cx.lit_str(v_span, v_name);
853-
let v_id = cx.lit_uint(v_span, vidx);
854-
let sz = cx.lit_uint(v_span, vec::len(variant_tys));
855-
let body = cx.lambda(blk);
856-
#ast[expr]{
857-
$(s).emit_enum_variant($(v_name), $(v_id),
858-
$(sz), $(body))
859-
}
860-
},
861-
862-
// Generate s.emit_enum_variant_arg(i, {|| blk })
863-
|-s, i, blk| {
864-
let idx = cx.lit_uint(v_span, i);
865-
let body = cx.lambda(blk);
866-
#ast[expr]{
867-
$(s).emit_enum_variant_arg($(idx), $(body))
868-
}
869-
})
833+
834+
match variant.node.kind {
835+
ast::tuple_variant_kind(args) => {
836+
let variant_tys = vec::map(args, |a| a.ty);
837+
838+
ser_variant(
839+
cx, tps, variant_tys, v_span, cx.clone(s),
840+
841+
// Generate pattern var(v1, v2, v3)
842+
|pats| {
843+
if vec::is_empty(pats) {
844+
ast::pat_ident(ast::bind_by_implicit_ref,
845+
cx.path(v_span, ~[v_name]),
846+
none)
847+
} else {
848+
ast::pat_enum(cx.path(v_span, ~[v_name]),
849+
some(pats))
850+
}
851+
},
852+
853+
// Generate body s.emit_enum_variant("foo", 0u,
854+
// 3u, {|| blk })
855+
|-s, blk| {
856+
let v_name = cx.lit_str(v_span, v_name);
857+
let v_id = cx.lit_uint(v_span, vidx);
858+
let sz = cx.lit_uint(v_span, vec::len(variant_tys));
859+
let body = cx.lambda(blk);
860+
#ast[expr]{
861+
$(s).emit_enum_variant($(v_name), $(v_id),
862+
$(sz), $(body))
863+
}
864+
},
865+
866+
// Generate s.emit_enum_variant_arg(i, {|| blk })
867+
|-s, i, blk| {
868+
let idx = cx.lit_uint(v_span, i);
869+
let body = cx.lambda(blk);
870+
#ast[expr]{
871+
$(s).emit_enum_variant_arg($(idx), $(body))
872+
}
873+
})
874+
}
875+
_ =>
876+
fail ~"struct variants unimplemented for auto serialize"
877+
}
870878
};
871879
let lam = cx.lambda(cx.blk(e_span, ~[cx.alt_stmt(arms, e_span, v)]));
872880
let e_name = cx.lit_str(e_span, e_name);
@@ -881,24 +889,32 @@ fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: ast::ident,
881889
let variant = variants[vidx];
882890
let v_span = variant.span;
883891
let v_name = variant.node.name;
884-
let tys = vec::map(variant.node.args, |a| a.ty);
885-
886-
let arg_exprs = do vec::from_fn(vec::len(tys)) |i| {
887-
let idx = cx.lit_uint(v_span, i);
888-
let body = deser_lambda(cx, tps, tys[i], cx.clone(d));
889-
#ast{ $(d).read_enum_variant_arg($(idx), $(body)) }
890-
};
891892

892-
let body = {
893-
if vec::is_empty(tys) {
894-
// for a nullary variant v, do "v"
895-
cx.var_ref(v_span, v_name)
896-
} else {
897-
// for an n-ary variant v, do "v(a_1, ..., a_n)"
898-
cx.expr(v_span, ast::expr_call(
899-
cx.var_ref(v_span, v_name), arg_exprs, false))
893+
let body;
894+
match variant.node.kind {
895+
ast::tuple_variant_kind(args) => {
896+
let tys = vec::map(args, |a| a.ty);
897+
898+
let arg_exprs = do vec::from_fn(vec::len(tys)) |i| {
899+
let idx = cx.lit_uint(v_span, i);
900+
let body = deser_lambda(cx, tps, tys[i], cx.clone(d));
901+
#ast{ $(d).read_enum_variant_arg($(idx), $(body)) }
902+
};
903+
904+
body = {
905+
if vec::is_empty(tys) {
906+
// for a nullary variant v, do "v"
907+
cx.var_ref(v_span, v_name)
908+
} else {
909+
// for an n-ary variant v, do "v(a_1, ..., a_n)"
910+
cx.expr(v_span, ast::expr_call(
911+
cx.var_ref(v_span, v_name), arg_exprs, false))
912+
}
913+
};
900914
}
901-
};
915+
ast::struct_variant_kind =>
916+
fail ~"struct variants unimplemented"
917+
}
902918

903919
{pats: ~[@{id: cx.next_id(),
904920
node: ast::pat_lit(cx.lit_uint(v_span, vidx)),

src/libsyntax/ext/pipes/ast_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
254254

255255
{node: {name: name,
256256
attrs: ~[],
257-
args: args,
257+
kind: ast::tuple_variant_kind(args),
258258
id: self.next_id(),
259259
disr_expr: none,
260260
vis: ast::public},

src/libsyntax/fold.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,15 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
541541
return {ty: fld.fold_ty(va.ty), id: fld.new_id(va.id)};
542542
}
543543
let fold_variant_arg = |x| fold_variant_arg_(x, fld);
544-
let args = vec::map(v.args, fold_variant_arg);
544+
545+
let kind;
546+
match v.kind {
547+
tuple_variant_kind(variant_args) =>
548+
kind = tuple_variant_kind(vec::map(variant_args,
549+
fold_variant_arg)),
550+
struct_variant_kind =>
551+
kind = struct_variant_kind
552+
}
545553

546554
let fold_attribute = |x| fold_attribute_(x, fld);
547555
let attrs = vec::map(v.attrs, fold_attribute);
@@ -552,7 +560,8 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
552560
};
553561
return {name: /* FIXME (#2543) */ copy v.name,
554562
attrs: attrs,
555-
args: args, id: fld.new_id(v.id),
563+
kind: kind,
564+
id: fld.new_id(v.id),
556565
disr_expr: de,
557566
vis: v.vis};
558567
}

src/libsyntax/parse/parser.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
4949
return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
5050
stmt_semi, subtract, sty_box, sty_by_ref, sty_region, sty_uniq,
5151
sty_value, token_tree, trait_method, trait_ref, tt_delim, tt_seq,
52-
tt_tok, tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn,
53-
ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_param_bound,
54-
ty_path, ty_ptr, ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq,
55-
ty_vec, ty_fixed_length, unchecked_blk, uniq, unsafe_blk,
56-
unsafe_fn, variant, view_item, view_item_, view_item_export,
57-
view_item_import, view_item_use, view_path, view_path_glob,
58-
view_path_list, view_path_simple, visibility, vstore, vstore_box,
59-
vstore_fixed, vstore_slice, vstore_uniq};
52+
tt_tok, tt_nonterminal, tuple_variant_kind, ty, ty_, ty_bot,
53+
ty_box, ty_field, ty_fn, ty_infer, ty_mac, ty_method, ty_nil,
54+
ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr,
55+
ty_tup, ty_u32, ty_uniq, ty_vec, ty_fixed_length, unchecked_blk,
56+
uniq, unsafe_blk, unsafe_fn, variant, view_item, view_item_,
57+
view_item_export, view_item_import, view_item_use, view_path,
58+
view_path_glob, view_path_list, view_path_simple, visibility,
59+
vstore, vstore_box, vstore_fixed, vstore_slice, vstore_uniq};
6060

6161
export file_type;
6262
export parser;
@@ -2830,7 +2830,8 @@ class parser {
28302830
spanned(ty.span.lo, ty.span.hi,
28312831
{name: id,
28322832
attrs: ~[],
2833-
args: ~[{ty: ty, id: self.get_id()}],
2833+
kind: tuple_variant_kind
2834+
(~[{ty: ty, id: self.get_id()}]),
28342835
id: self.get_id(),
28352836
disr_expr: none,
28362837
vis: public});
@@ -2861,7 +2862,7 @@ class parser {
28612862
}
28622863

28632864
let vr = {name: ident, attrs: variant_attrs,
2864-
args: args, id: self.get_id(),
2865+
kind: tuple_variant_kind(args), id: self.get_id(),
28652866
disr_expr: disr_expr, vis: vis};
28662867
vec::push(variants, spanned(vlo, self.last_span.hi, vr));
28672868

src/libsyntax/print/pprust.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -488,21 +488,31 @@ fn print_item(s: ps, &&item: @ast::item) {
488488
end(s); // end the outer ibox
489489
}
490490
ast::item_enum(variants, params) => {
491-
let newtype =
491+
let mut newtype =
492492
vec::len(variants) == 1u &&
493-
str::eq(item.ident, variants[0].node.name) &&
494-
vec::len(variants[0].node.args) == 1u;
493+
str::eq(item.ident, variants[0].node.name);
494+
if newtype {
495+
match variants[0].node.kind {
496+
ast::tuple_variant_kind(args) if args.len() == 1 => {}
497+
_ => newtype = false
498+
}
499+
}
495500
if newtype {
496501
ibox(s, indent_unit);
497502
word_space(s, ~"enum");
498-
} else { head(s, ~"enum"); }
503+
} else {
504+
head(s, ~"enum");
505+
}
499506

500507
word(s.s, *item.ident);
501508
print_type_params(s, params);
502509
space(s.s);
503510
if newtype {
504511
word_space(s, ~"=");
505-
print_type(s, variants[0].node.args[0].ty);
512+
match variants[0].node.kind {
513+
ast::tuple_variant_kind(args) => print_type(s, args[0].ty),
514+
_ => fail ~"newtype syntax with struct?"
515+
}
506516
word(s.s, ~";");
507517
end(s);
508518
} else {
@@ -680,13 +690,18 @@ fn print_tt(s: ps, tt: ast::token_tree) {
680690

681691
fn print_variant(s: ps, v: ast::variant) {
682692
word(s.s, *v.node.name);
683-
if vec::len(v.node.args) > 0u {
684-
popen(s);
685-
fn print_variant_arg(s: ps, arg: ast::variant_arg) {
686-
print_type(s, arg.ty);
693+
match v.node.kind {
694+
ast::tuple_variant_kind(args) => {
695+
if vec::len(args) > 0u {
696+
popen(s);
697+
fn print_variant_arg(s: ps, arg: ast::variant_arg) {
698+
print_type(s, arg.ty);
699+
}
700+
commasep(s, consistent, args, print_variant_arg);
701+
pclose(s);
702+
}
687703
}
688-
commasep(s, consistent, v.node.args, print_variant_arg);
689-
pclose(s);
704+
ast::struct_variant_kind => {}
690705
}
691706
match v.node.disr_expr {
692707
some(d) => {

src/libsyntax/visit.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
135135
item_enum(variants, tps) => {
136136
v.visit_ty_params(tps, e, v);
137137
for variants.each |vr| {
138-
for vr.node.args.each |va| { v.visit_ty(va.ty, e, v); }
138+
match vr.node.kind {
139+
tuple_variant_kind(variant_args) =>
140+
for variant_args.each |va| { v.visit_ty(va.ty, e, v); },
141+
struct_variant_kind => {}
142+
}
139143
}
140144
}
141145
item_impl(tps, traits, ty, methods) => {

src/rustc/metadata/encoder.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,12 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
362362
encode_parent_item(ebml_w, local_def(id));
363363
encode_type(ecx, ebml_w,
364364
node_id_to_type(ecx.tcx, variant.node.id));
365-
if vec::len(variant.node.args) > 0u && ty_params.len() == 0u {
366-
encode_symbol(ecx, ebml_w, variant.node.id);
365+
match variant.node.kind {
366+
ast::tuple_variant_kind(args)
367+
if args.len() > 0 && ty_params.len() == 0 => {
368+
encode_symbol(ecx, ebml_w, variant.node.id);
369+
}
370+
ast::tuple_variant_kind(_) | ast::struct_variant_kind => {}
367371
}
368372
encode_discriminant(ecx, ebml_w, variant.node.id);
369373
if vi[i].disr_val != disr_val {

0 commit comments

Comments
 (0)