Skip to content

Commit f110e8f

Browse files
committed
rustc: Do some plumbing work on nested enums
1 parent 166cb1b commit f110e8f

File tree

12 files changed

+250
-157
lines changed

12 files changed

+250
-157
lines changed

src/libsyntax/ast.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,8 @@ type variant_arg = {ty: @ty, id: node_id};
636636
#[auto_serialize]
637637
enum variant_kind {
638638
tuple_variant_kind(~[variant_arg]),
639-
struct_variant_kind(@struct_def)
639+
struct_variant_kind(@struct_def),
640+
enum_variant_kind(~[variant])
640641
}
641642

642643
#[auto_serialize]

src/libsyntax/ext/auto_serialize.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,9 @@ fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: ast::ident,
913913
};
914914
}
915915
ast::struct_variant_kind(*) =>
916-
fail ~"struct variants unimplemented"
916+
fail ~"struct variants unimplemented",
917+
ast::enum_variant_kind(*) =>
918+
fail ~"enum variants unimplemented"
917919
}
918920

919921
{pats: ~[@{id: cx.next_id(),

src/libsyntax/fold.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,11 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
564564
dtor: dtor
565565
})
566566
}
567+
568+
enum_variant_kind(variants) => {
569+
let variants = vec::map(variants, |x| fld.fold_variant(x));
570+
kind = enum_variant_kind(variants);
571+
}
567572
}
568573

569574
let fold_attribute = |x| fold_attribute_(x, fld);

src/libsyntax/parse/parser.rs

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,27 @@ import dvec::{dvec, extensions};
1717
import vec::{push};
1818
import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
1919
bind_by_ref, bind_by_implicit_ref, bind_by_value,
20-
bitand, bitor, bitxor, blk,
21-
blk_check_mode, bound_const, bound_copy, bound_send, bound_trait,
22-
bound_owned, box, by_copy, by_move, by_mutbl_ref, by_ref, by_val,
23-
capture_clause, capture_item, cdir_dir_mod, cdir_src_mod,
24-
cdir_view_item, class_immutable, class_member, class_method,
25-
class_mutable, crate, crate_cfg, crate_directive, decl,
26-
decl_item, decl_local, default_blk, deref, div, expl, expr,
27-
expr_, expr_addr_of, expr_match, expr_again, expr_assert,
28-
expr_assign, expr_assign_op, expr_binary, expr_block, expr_break,
29-
expr_call, expr_cast, expr_copy, expr_do_body,
30-
expr_fail, expr_field, expr_fn, expr_fn_block, expr_if,
31-
expr_index, expr_lit, expr_log, expr_loop,
32-
expr_loop_body, expr_mac, expr_move, expr_path, expr_rec,
33-
expr_repeat, expr_ret, expr_swap, expr_struct, expr_tup,
34-
expr_unary, expr_unary_move, expr_vec, expr_vstore, expr_while,
35-
extern_fn, field, fn_decl, foreign_item, foreign_item_fn,
36-
foreign_mod, ident, impure_fn, infer, inherited, init_assign,
37-
init_move, initializer, instance_var, item, item_, item_class,
38-
item_const, item_enum, item_fn, item_foreign_mod, item_impl,
39-
item_mac, item_mod, item_trait, item_ty, lit, lit_, lit_bool,
40-
lit_float, lit_int, lit_int_unsuffixed, lit_nil, lit_str,
41-
lit_uint, local, m_const, m_imm, m_mutbl, mac_, mac_aq,
20+
bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
21+
bound_copy, bound_send, bound_trait, bound_owned, box, by_copy,
22+
by_move, by_mutbl_ref, by_ref, by_val, capture_clause,
23+
capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
24+
class_immutable, class_member, class_method, class_mutable,
25+
crate, crate_cfg, crate_directive, decl, decl_item, decl_local,
26+
default_blk, deref, div, enum_variant_kind, expl, expr, expr_,
27+
expr_addr_of, expr_match, expr_again, expr_assert, expr_assign,
28+
expr_assign_op, expr_binary, expr_block, expr_break, expr_call,
29+
expr_cast, expr_copy, expr_do_body, expr_fail, expr_field,
30+
expr_fn, expr_fn_block, expr_if, expr_index, expr_lit, expr_log,
31+
expr_loop, expr_loop_body, expr_mac, expr_move, expr_path,
32+
expr_rec, expr_repeat, expr_ret, expr_swap, expr_struct,
33+
expr_tup, expr_unary, expr_unary_move, expr_vec, expr_vstore,
34+
expr_while, extern_fn, field, fn_decl, foreign_item,
35+
foreign_item_fn, foreign_mod, ident, impure_fn, infer, inherited,
36+
init_assign, init_move, initializer, instance_var, item, item_,
37+
item_class, item_const, item_enum, item_fn, item_foreign_mod,
38+
item_impl, item_mac, item_mod, item_trait, item_ty, lit, lit_,
39+
lit_bool, lit_float, lit_int, lit_int_unsuffixed, lit_nil,
40+
lit_str, lit_uint, local, m_const, m_imm, m_mutbl, mac_, mac_aq,
4241
mac_ellipsis, mac_invoc, mac_invoc_tt, mac_var, matcher,
4342
match_nonterminal, match_seq, match_tok, method, mode, mt, mul,
4443
mutability, neg, noreturn, not, pat, pat_box, pat_enum,
@@ -2842,30 +2841,8 @@ class parser {
28422841
}
28432842
}
28442843

2845-
fn parse_item_enum() -> item_info {
2846-
let id = self.parse_ident();
2847-
self.parse_region_param();
2848-
let ty_params = self.parse_ty_params();
2844+
fn parse_enum_body(ty_params: ~[ast::ty_param]) -> ~[ast::variant] {
28492845
let mut variants: ~[variant] = ~[];
2850-
// Newtype syntax
2851-
if self.token == token::EQ {
2852-
self.check_restricted_keywords_(*id);
2853-
self.bump();
2854-
let ty = self.parse_ty(false);
2855-
self.expect(token::SEMI);
2856-
let variant =
2857-
spanned(ty.span.lo, ty.span.hi,
2858-
{name: id,
2859-
attrs: ~[],
2860-
kind: tuple_variant_kind
2861-
(~[{ty: ty, id: self.get_id()}]),
2862-
id: self.get_id(),
2863-
disr_expr: none,
2864-
vis: public});
2865-
return (id, item_enum(~[variant], ty_params), none);
2866-
}
2867-
self.expect(token::LBRACE);
2868-
28692846
let mut all_nullary = true, have_disr = false;
28702847

28712848
while self.token != token::RBRACE {
@@ -2954,6 +2931,34 @@ class parser {
29542931
self.fatal(~"discriminator values can only be used with a c-like \
29552932
enum");
29562933
}
2934+
2935+
return variants;
2936+
}
2937+
2938+
fn parse_item_enum() -> item_info {
2939+
let id = self.parse_ident();
2940+
self.parse_region_param();
2941+
let ty_params = self.parse_ty_params();
2942+
// Newtype syntax
2943+
if self.token == token::EQ {
2944+
self.check_restricted_keywords_(*id);
2945+
self.bump();
2946+
let ty = self.parse_ty(false);
2947+
self.expect(token::SEMI);
2948+
let variant =
2949+
spanned(ty.span.lo, ty.span.hi,
2950+
{name: id,
2951+
attrs: ~[],
2952+
kind: tuple_variant_kind
2953+
(~[{ty: ty, id: self.get_id()}]),
2954+
id: self.get_id(),
2955+
disr_expr: none,
2956+
vis: public});
2957+
return (id, item_enum(~[variant], ty_params), none);
2958+
}
2959+
self.expect(token::LBRACE);
2960+
2961+
let variants = self.parse_enum_body(ty_params);
29572962
(id, item_enum(variants, ty_params), none)
29582963
}
29592964

src/libsyntax/print/pprust.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -516,18 +516,7 @@ fn print_item(s: ps, &&item: @ast::item) {
516516
word(s.s, ~";");
517517
end(s);
518518
} else {
519-
bopen(s);
520-
for variants.each |v| {
521-
space_if_not_bol(s);
522-
maybe_print_comment(s, v.span.lo);
523-
print_outer_attributes(s, v.node.attrs);
524-
ibox(s, indent_unit);
525-
print_variant(s, v);
526-
word(s.s, ~",");
527-
end(s);
528-
maybe_print_trailing_comment(s, v.span, none::<uint>);
529-
}
530-
bclose(s, item.span);
519+
print_variants(s, variants, item.span);
531520
}
532521
}
533522
ast::item_class(struct_def, tps) => {
@@ -582,6 +571,21 @@ fn print_item(s: ps, &&item: @ast::item) {
582571
s.ann.post(ann_node);
583572
}
584573

574+
fn print_variants(s: ps, variants: ~[ast::variant], span: ast::span) {
575+
bopen(s);
576+
for variants.each |v| {
577+
space_if_not_bol(s);
578+
maybe_print_comment(s, v.span.lo);
579+
print_outer_attributes(s, v.node.attrs);
580+
ibox(s, indent_unit);
581+
print_variant(s, v);
582+
word(s.s, ~",");
583+
end(s);
584+
maybe_print_trailing_comment(s, v.span, none::<uint>);
585+
}
586+
bclose(s, span);
587+
}
588+
585589
fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param],
586590
ident: ast::ident, span: ast::span) {
587591
word_nbsp(s, *ident);
@@ -710,6 +714,9 @@ fn print_variant(s: ps, v: ast::variant) {
710714
head(s, ~"");
711715
print_struct(s, struct_def, ~[], v.node.name, v.span);
712716
}
717+
ast::enum_variant_kind(variants) => {
718+
print_variants(s, variants, v.span);
719+
}
713720
}
714721
match v.node.disr_expr {
715722
some(d) => {

src/libsyntax/visit.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
138138
}
139139
item_enum(variants, tps) => {
140140
v.visit_ty_params(tps, e, v);
141-
for variants.each |vr| {
142-
match vr.node.kind {
143-
tuple_variant_kind(variant_args) => {
144-
for variant_args.each |va| { v.visit_ty(va.ty, e, v); }
145-
}
146-
struct_variant_kind(struct_def) => {
147-
v.visit_struct_def(struct_def, vr.node.name, tps,
148-
vr.node.id, e, v);
149-
}
150-
}
151-
}
141+
visit_variants(variants, tps, e, v);
152142
}
153143
item_impl(tps, traits, ty, methods) => {
154144
v.visit_ty_params(tps, e, v);
@@ -175,6 +165,24 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
175165
}
176166
}
177167

168+
fn visit_variants<E>(variants: ~[ast::variant], tps: ~[ast::ty_param], e: E,
169+
v: vt<E>) {
170+
for variants.each |vr| {
171+
match vr.node.kind {
172+
tuple_variant_kind(variant_args) => {
173+
for variant_args.each |va| { v.visit_ty(va.ty, e, v); }
174+
}
175+
struct_variant_kind(struct_def) => {
176+
v.visit_struct_def(struct_def, vr.node.name, tps,
177+
vr.node.id, e, v);
178+
}
179+
enum_variant_kind(variants) => {
180+
visit_variants(variants, tps, e, v);
181+
}
182+
}
183+
}
184+
}
185+
178186
fn visit_class_item<E>(cm: @class_member, e:E, v:vt<E>) {
179187
match cm.node {
180188
instance_var(_, t, _, _, _) => v.visit_ty(t, e, v),

src/rustc/metadata/encoder.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,8 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
398398
if args.len() > 0 && ty_params.len() == 0 => {
399399
encode_symbol(ecx, ebml_w, variant.node.id);
400400
}
401-
ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) => {}
401+
ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) |
402+
ast::enum_variant_kind(_) => {}
402403
}
403404
encode_discriminant(ecx, ebml_w, variant.node.id);
404405
if vi[i].disr_val != disr_val {

src/rustc/middle/resolve3.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@ import syntax::ast::{def_upvar, def_use, def_variant, expr, expr_assign_op};
2121
import syntax::ast::{expr_binary, expr_cast, expr_field, expr_fn};
2222
import syntax::ast::{expr_fn_block, expr_index, expr_path};
2323
import syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
24-
import syntax::ast::{def_upvar, def_use, def_variant, div, eq, expr};
25-
import syntax::ast::{expr_assign_op, expr_binary, expr_cast, expr_field};
26-
import syntax::ast::{expr_fn, expr_fn_block, expr_index, expr_path};
27-
import syntax::ast::{expr_struct, expr_unary, fn_decl, foreign_item};
28-
import syntax::ast::{foreign_item_fn, ge, gt, ident, trait_ref, impure_fn};
29-
import syntax::ast::{instance_var, item, item_class, item_const, item_enum};
30-
import syntax::ast::{item_fn, item_mac, item_foreign_mod, item_impl};
31-
import syntax::ast::{item_mod, item_trait, item_ty, le, local, local_crate};
32-
import syntax::ast::{lt, method, mul, ne, neg, node_id, pat, pat_enum};
33-
import syntax::ast::{pat_ident, path, prim_ty, pat_box, pat_uniq, pat_lit};
34-
import syntax::ast::{pat_range, pat_rec, pat_struct, pat_tup, pat_wild};
35-
import syntax::ast::{provided, required, rem, self_ty_, shl, stmt_decl};
36-
import syntax::ast::{struct_variant_kind, sty_static, subtract};
24+
import syntax::ast::{def_upvar, def_use, def_variant, div, eq};
25+
import syntax::ast::{enum_variant_kind, expr, expr_assign_op, expr_binary};
26+
import syntax::ast::{expr_cast, expr_field, expr_fn, expr_fn_block};
27+
import syntax::ast::{expr_index, expr_path, expr_struct, expr_unary, fn_decl};
28+
import syntax::ast::{foreign_item, foreign_item_fn, ge, gt, ident, trait_ref};
29+
import syntax::ast::{impure_fn, instance_var, item, item_class, item_const};
30+
import syntax::ast::{item_enum, item_fn, item_mac, item_foreign_mod};
31+
import syntax::ast::{item_impl, item_mod, item_trait, item_ty, le, local};
32+
import syntax::ast::{local_crate, lt, method, mul, ne, neg, node_id, pat};
33+
import syntax::ast::{pat_enum, pat_ident, path, prim_ty, pat_box, pat_uniq};
34+
import syntax::ast::{pat_lit, pat_range, pat_rec, pat_struct, pat_tup};
35+
import syntax::ast::{pat_wild, provided, required, rem, self_ty_, shl};
36+
import syntax::ast::{stmt_decl, struct_variant_kind, sty_static, subtract};
3737
import syntax::ast::{tuple_variant_kind, ty};
3838
import syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i};
3939
import syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, ty_param};
@@ -1128,7 +1128,7 @@ class Resolver {
11281128
fn build_reduced_graph_for_variant(variant: variant,
11291129
item_id: def_id,
11301130
parent: ReducedGraphParent,
1131-
&&_visitor: vt<ReducedGraphParent>) {
1131+
&&visitor: vt<ReducedGraphParent>) {
11321132

11331133
let atom = (*self.atom_table).intern(variant.node.name);
11341134
let (child, _) = self.add_child(atom, parent, ~[ValueNS],
@@ -1146,6 +1146,14 @@ class Resolver {
11461146
variant.span);
11471147
self.structs.insert(local_def(variant.node.id), false);
11481148
}
1149+
enum_variant_kind(variants) => {
1150+
(*child).define_type(def_ty(local_def(variant.node.id)),
1151+
variant.span);
1152+
for variants.each |variant| {
1153+
self.build_reduced_graph_for_variant(variant, item_id,
1154+
parent, visitor);
1155+
}
1156+
}
11491157
}
11501158
}
11511159

src/rustc/middle/trans/base.rs

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,7 +2235,9 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id,
22352235
psubsts, d);
22362236
}
22372237
ast::struct_variant_kind(_) =>
2238-
ccx.tcx.sess.bug(~"can't monomorphize struct variants")
2238+
ccx.tcx.sess.bug(~"can't monomorphize struct variants"),
2239+
ast::enum_variant_kind(_) =>
2240+
ccx.tcx.sess.bug(~"can't monomorphize enum variants")
22392241
}
22402242
d
22412243
}
@@ -4893,6 +4895,34 @@ fn trans_class_dtor(ccx: @crate_ctxt, path: path,
48934895
lldecl
48944896
}
48954897

4898+
fn trans_variants(ccx: @crate_ctxt, variants: ~[ast::variant],
4899+
id: ast::node_id, tps: ~[ast::ty_param], degen: bool,
4900+
path: @ast_map::path, vi: @~[ty::variant_info],
4901+
i: &mut uint) {
4902+
for vec::each(variants) |variant| {
4903+
let disr_val = vi[*i].disr_val;
4904+
*i += 1;
4905+
4906+
match variant.node.kind {
4907+
ast::tuple_variant_kind(args) if args.len() > 0 => {
4908+
let llfn = get_item_val(ccx, variant.node.id);
4909+
trans_enum_variant(ccx, id, variant, args, disr_val,
4910+
degen, none, llfn);
4911+
}
4912+
ast::tuple_variant_kind(_) => {
4913+
// Nothing to do.
4914+
}
4915+
ast::struct_variant_kind(struct_def) => {
4916+
trans_struct_def(ccx, struct_def, tps, path,
4917+
variant.node.name, variant.node.id);
4918+
}
4919+
ast::enum_variant_kind(variants) => {
4920+
trans_variants(ccx, variants, id, tps, degen, path, vi, i);
4921+
}
4922+
}
4923+
}
4924+
}
4925+
48964926
fn trans_item(ccx: @crate_ctxt, item: ast::item) {
48974927
let _icx = ccx.insn_ctxt(~"trans_item");
48984928
let path = match check ccx.tcx.items.get(item.id) {
@@ -4934,24 +4964,8 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
49344964
let degen = variants.len() == 1u;
49354965
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
49364966
let mut i = 0;
4937-
for vec::each(variants) |variant| {
4938-
match variant.node.kind {
4939-
ast::tuple_variant_kind(args) if args.len() > 0 => {
4940-
let llfn = get_item_val(ccx, variant.node.id);
4941-
trans_enum_variant(ccx, item.id, variant, args,
4942-
vi[i].disr_val, degen,
4943-
none, llfn);
4944-
}
4945-
ast::tuple_variant_kind(_) => {
4946-
// Nothing to do.
4947-
}
4948-
ast::struct_variant_kind(struct_def) => {
4949-
trans_struct_def(ccx, struct_def, tps, path,
4950-
variant.node.name, variant.node.id);
4951-
}
4952-
}
4953-
i += 1;
4954-
}
4967+
trans_variants(ccx, variants, item.id, tps, degen, path, vi,
4968+
&mut i);
49554969
}
49564970
}
49574971
ast::item_const(_, expr) => consts::trans_const(ccx, expr, item.id),
@@ -5263,7 +5277,10 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
52635277
};
52645278
}
52655279
ast::struct_variant_kind(_) => {
5266-
fail ~"struct unexpected in get_item_val"
5280+
fail ~"struct variant kind unexpected in get_item_val"
5281+
}
5282+
ast::enum_variant_kind(_) => {
5283+
fail ~"enum variant kind unexpected in get_item_val"
52675284
}
52685285
}
52695286
set_inline_hint(llfn);

0 commit comments

Comments
 (0)