1
Fork 0

rustc: Do some plumbing work in preparation for common fields in enums

This commit is contained in:
Patrick Walton 2012-08-08 17:14:25 -07:00
parent 35db5b7be1
commit 4f98e80db1
21 changed files with 134 additions and 116 deletions

View file

@ -637,9 +637,12 @@ type variant_arg = {ty: @ty, id: node_id};
enum variant_kind {
tuple_variant_kind(~[variant_arg]),
struct_variant_kind(@struct_def),
enum_variant_kind(~[variant])
enum_variant_kind(enum_def)
}
#[auto_serialize]
enum enum_def = { variants: ~[variant] };
#[auto_serialize]
type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind,
id: node_id, disr_expr: option<@expr>, vis: visibility};
@ -736,7 +739,7 @@ enum item_ {
item_mod(_mod),
item_foreign_mod(foreign_mod),
item_ty(@ty, ~[ty_param]),
item_enum(~[variant], ~[ty_param]),
item_enum(enum_def, ~[ty_param]),
item_class(@struct_def, ~[ty_param]),
item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
item_impl(~[ty_param],

View file

@ -197,8 +197,8 @@ fn map_item(i: @item, cx: ctx, v: vt) {
cx);
}
}
item_enum(vs, _) => {
for vs.each |v| {
item_enum(enum_definition, _) => {
for enum_definition.variants.each |v| {
cx.map.insert(v.node.id, node_variant(
/* FIXME (#2543) */ copy v, i,
extend(cx, i.ident)));

View file

@ -187,8 +187,8 @@ fn is_exported(i: ident, m: _mod) -> bool {
for m.items.each |it| {
if it.ident == i { local = true; }
match it.node {
item_enum(variants, _) =>
for variants.each |v| {
item_enum(enum_definition, _) =>
for enum_definition.variants.each |v| {
if v.node.name == i {
local = true;
parent_enum = some(/* FIXME (#2543) */ copy it.ident);
@ -477,7 +477,8 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> {
visit_item: fn@(i: @item) {
vfn(i.id);
match i.node {
item_enum(vs, _) => for vs.each |v| { vfn(v.node.id); },
item_enum(enum_definition, _) =>
for enum_definition.variants.each |v| { vfn(v.node.id); },
_ => ()
}
},

View file

@ -107,10 +107,10 @@ fn expand(cx: ext_ctxt,
ty_fns(cx, in_item.ident, ty, tps))
}
ast::item_enum(variants, tps) => {
ast::item_enum(enum_definition, tps) => {
vec::append(~[filter_attrs(in_item)],
enum_fns(cx, in_item.ident,
in_item.span, variants, tps))
in_item.span, enum_definition.variants, tps))
}
_ => {

View file

@ -66,9 +66,9 @@ trait ext_ctxt_ast_builder {
output: @ast::ty,
+body: ast::blk) -> @ast::item;
fn item_enum_poly(name: ident,
+variants: ~[ast::variant],
+enum_definition: ast::enum_def,
+ty_params: ~[ast::ty_param]) -> @ast::item;
fn item_enum(name: ident, +variants: ~[ast::variant]) -> @ast::item;
fn item_enum(name: ident, +enum_definition: ast::enum_def) -> @ast::item;
fn variant(name: ident, +tys: ~[@ast::ty]) -> ast::variant;
fn item_mod(name: ident, +items: ~[@ast::item]) -> @ast::item;
fn ty_path_ast_builder(path: @ast::path) -> @ast::ty;
@ -236,16 +236,13 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
}
fn item_enum_poly(name: ident,
+variants: ~[ast::variant],
+enum_definition: ast::enum_def,
+ty_params: ~[ast::ty_param]) -> @ast::item {
self.item(name,
ast::item_enum(variants,
ty_params))
self.item(name, ast::item_enum(enum_definition, ty_params))
}
fn item_enum(name: ident,
+variants: ~[ast::variant]) -> @ast::item {
self.item_enum_poly(name, variants, ~[])
fn item_enum(name: ident, +enum_definition: ast::enum_def) -> @ast::item {
self.item_enum_poly(name, enum_definition, ~[])
}
fn variant(name: ident,

View file

@ -237,7 +237,8 @@ impl compile of to_type_decls for state {
vec::push(items_msg, v);
}
~[cx.item_enum_poly(name, items_msg, self.ty_params)]
~[cx.item_enum_poly(name, ast::enum_def({ variants: items_msg }),
self.ty_params)]
}
fn to_endpoint_decls(cx: ext_ctxt, dir: direction) -> ~[@ast::item] {

View file

@ -238,9 +238,11 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
item_foreign_mod(nm) => item_foreign_mod(fld.fold_foreign_mod(nm)),
item_ty(t, typms) => item_ty(fld.fold_ty(t),
fold_ty_params(typms, fld)),
item_enum(variants, typms) => {
item_enum(vec::map(variants, |x| fld.fold_variant(x)),
fold_ty_params(typms, fld))
item_enum(enum_definition, typms) => {
item_enum(ast::enum_def({
variants: vec::map(enum_definition.variants,
|x| fld.fold_variant(x)),
}), fold_ty_params(typms, fld))
}
item_class(struct_def, typms) => {
let resulting_optional_constructor;
@ -565,9 +567,10 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
})
}
enum_variant_kind(variants) => {
let variants = vec::map(variants, |x| fld.fold_variant(x));
kind = enum_variant_kind(variants);
enum_variant_kind(enum_definition) => {
let variants = vec::map(enum_definition.variants,
|x| fld.fold_variant(x));
kind = enum_variant_kind(ast::enum_def({ variants: variants }));
}
}

View file

@ -23,15 +23,15 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
class_immutable, class_member, class_method, class_mutable,
crate, crate_cfg, crate_directive, decl, decl_item, decl_local,
default_blk, deref, div, enum_variant_kind, expl, expr, expr_,
expr_addr_of, expr_match, expr_again, expr_assert, expr_assign,
expr_assign_op, expr_binary, expr_block, expr_break, expr_call,
expr_cast, expr_copy, expr_do_body, expr_fail, expr_field,
expr_fn, expr_fn_block, expr_if, expr_index, expr_lit, expr_log,
expr_loop, expr_loop_body, expr_mac, expr_move, expr_path,
expr_rec, expr_repeat, expr_ret, expr_swap, expr_struct,
expr_tup, expr_unary, expr_unary_move, expr_vec, expr_vstore,
expr_while, extern_fn, field, fn_decl, foreign_item,
default_blk, deref, div, enum_def, enum_variant_kind, expl, expr,
expr_, expr_addr_of, expr_match, expr_again, expr_assert,
expr_assign, expr_assign_op, expr_binary, expr_block, expr_break,
expr_call, expr_cast, expr_copy, expr_do_body, expr_fail,
expr_field, expr_fn, expr_fn_block, expr_if, expr_index,
expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac,
expr_move, expr_path, expr_rec, expr_repeat, expr_ret, expr_swap,
expr_struct, expr_tup, expr_unary, expr_unary_move, expr_vec,
expr_vstore, expr_while, extern_fn, field, fn_decl, foreign_item,
foreign_item_fn, foreign_mod, ident, impure_fn, infer, inherited,
init_assign, init_move, initializer, instance_var, item, item_,
item_class, item_const, item_enum, item_fn, item_foreign_mod,
@ -2841,7 +2841,7 @@ class parser {
}
}
fn parse_enum_body(ty_params: ~[ast::ty_param]) -> ~[ast::variant] {
fn parse_enum_def(ty_params: ~[ast::ty_param]) -> enum_def {
let mut variants: ~[variant] = ~[];
let mut all_nullary = true, have_disr = false;
@ -2932,7 +2932,7 @@ class parser {
enum");
}
return variants;
return enum_def({ variants: variants });
}
fn parse_item_enum() -> item_info {
@ -2954,12 +2954,13 @@ class parser {
id: self.get_id(),
disr_expr: none,
vis: public});
return (id, item_enum(~[variant], ty_params), none);
return (id, item_enum(enum_def({ variants: ~[variant] }),
ty_params), none);
}
self.expect(token::LBRACE);
let variants = self.parse_enum_body(ty_params);
(id, item_enum(variants, ty_params), none)
let enum_definition = self.parse_enum_def(ty_params);
(id, item_enum(enum_definition, ty_params), none)
}
fn parse_fn_ty_proto() -> proto {

View file

@ -487,37 +487,8 @@ fn print_item(s: ps, &&item: @ast::item) {
word(s.s, ~";");
end(s); // end the outer ibox
}
ast::item_enum(variants, params) => {
let mut newtype =
vec::len(variants) == 1u &&
str::eq(item.ident, variants[0].node.name);
if newtype {
match variants[0].node.kind {
ast::tuple_variant_kind(args) if args.len() == 1 => {}
_ => newtype = false
}
}
if newtype {
ibox(s, indent_unit);
word_space(s, ~"enum");
} else {
head(s, ~"enum");
}
word(s.s, *item.ident);
print_type_params(s, params);
space(s.s);
if newtype {
word_space(s, ~"=");
match variants[0].node.kind {
ast::tuple_variant_kind(args) => print_type(s, args[0].ty),
_ => fail ~"newtype syntax with struct?"
}
word(s.s, ~";");
end(s);
} else {
print_variants(s, variants, item.span);
}
ast::item_enum(enum_definition, params) => {
print_enum_def(s, enum_definition, params, item.ident, item.span);
}
ast::item_class(struct_def, tps) => {
head(s, ~"class");
@ -571,6 +542,41 @@ fn print_item(s: ps, &&item: @ast::item) {
s.ann.post(ann_node);
}
fn print_enum_def(s: ps, enum_definition: ast::enum_def,
params: ~[ast::ty_param], ident: ast::ident,
span: ast::span) {
let mut newtype =
vec::len(enum_definition.variants) == 1u &&
str::eq(ident, enum_definition.variants[0].node.name);
if newtype {
match enum_definition.variants[0].node.kind {
ast::tuple_variant_kind(args) if args.len() == 1 => {}
_ => newtype = false
}
}
if newtype {
ibox(s, indent_unit);
word_space(s, ~"enum");
} else {
head(s, ~"enum");
}
word(s.s, *ident);
print_type_params(s, params);
space(s.s);
if newtype {
word_space(s, ~"=");
match enum_definition.variants[0].node.kind {
ast::tuple_variant_kind(args) => print_type(s, args[0].ty),
_ => fail ~"newtype syntax with struct?"
}
word(s.s, ~";");
end(s);
} else {
print_variants(s, enum_definition.variants, span);
}
}
fn print_variants(s: ps, variants: ~[ast::variant], span: ast::span) {
bopen(s);
for variants.each |v| {
@ -714,8 +720,8 @@ fn print_variant(s: ps, v: ast::variant) {
head(s, ~"");
print_struct(s, struct_def, ~[], v.node.name, v.span);
}
ast::enum_variant_kind(variants) => {
print_variants(s, variants, v.span);
ast::enum_variant_kind(enum_definition) => {
print_variants(s, enum_definition.variants, v.span);
}
}
match v.node.disr_expr {

View file

@ -136,9 +136,9 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
v.visit_ty(t, e, v);
v.visit_ty_params(tps, e, v);
}
item_enum(variants, tps) => {
item_enum(enum_definition, tps) => {
v.visit_ty_params(tps, e, v);
visit_variants(variants, tps, e, v);
visit_enum_def(enum_definition, tps, e, v);
}
item_impl(tps, traits, ty, methods) => {
v.visit_ty_params(tps, e, v);
@ -165,9 +165,9 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
}
}
fn visit_variants<E>(variants: ~[ast::variant], tps: ~[ast::ty_param], e: E,
v: vt<E>) {
for variants.each |vr| {
fn visit_enum_def<E>(enum_definition: ast::enum_def, tps: ~[ast::ty_param],
e: E, v: vt<E>) {
for enum_definition.variants.each |vr| {
match vr.node.kind {
tuple_variant_kind(variant_args) => {
for variant_args.each |va| { v.visit_ty(va.ty, e, v); }
@ -176,8 +176,8 @@ fn visit_variants<E>(variants: ~[ast::variant], tps: ~[ast::ty_param], e: E,
v.visit_struct_def(struct_def, vr.node.name, tps,
vr.node.id, e, v);
}
enum_variant_kind(variants) => {
visit_variants(variants, tps, e, v);
enum_variant_kind(enum_definition) => {
visit_enum_def(enum_definition, tps, e, v);
}
}
}

View file

@ -223,11 +223,12 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
encode_struct_def(ebml_w, struct_def, path, it.ident, index);
}
}
item_enum(variants, _) => {
item_enum(enum_definition, _) => {
do ebml_w.wr_tag(tag_paths_data_item) {
encode_name_and_def_id(ebml_w, it.ident, it.id);
}
encode_enum_variant_paths(ebml_w, variants, path, index);
encode_enum_variant_paths(ebml_w, enum_definition.variants,
path, index);
}
item_trait(_, _, methods) => {
do ebml_w.wr_tag(tag_paths_data_item) {
@ -723,7 +724,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_region_param(ecx, ebml_w, item);
ebml_w.end_tag();
}
item_enum(variants, tps) => {
item_enum(enum_definition, tps) => {
add_to_index();
do ebml_w.wr_tag(tag_items_data_item) {
encode_def_id(ebml_w, local_def(item.id));
@ -731,15 +732,15 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
encode_name(ebml_w, item.ident);
for variants.each |v| {
for enum_definition.variants.each |v| {
encode_variant_id(ebml_w, local_def(v.node.id));
}
ecx.encode_inlined_item(ecx, ebml_w, path, ii_item(item));
encode_path(ebml_w, path, ast_map::path_name(item.ident));
encode_region_param(ecx, ebml_w, item);
}
encode_enum_variant_info(ecx, ebml_w, item.id, variants,
path, index, tps);
encode_enum_variant_info(ecx, ebml_w, item.id,
enum_definition.variants, path, index, tps);
}
item_class(struct_def, tps) => {
/* First, encode the fields and methods

View file

@ -25,8 +25,8 @@ fn check_item(sess: session, ast_map: ast_map::map,
v.visit_expr(ex, true, v);
check_item_recursion(sess, ast_map, def_map, it);
}
item_enum(vs, _) => {
for vs.each |var| {
item_enum(enum_definition, _) => {
for enum_definition.variants.each |var| {
do option::iter(var.node.disr_expr) |ex| {
v.visit_expr(ex, true, v);
}

View file

@ -482,9 +482,9 @@ fn check_item_non_camel_case_types(cx: ty::ctxt, it: @ast::item) {
ast::item_trait(*) | ast::item_impl(*) => {
check_case(cx, it.ident, it.id, it.id, it.span)
}
ast::item_enum(variants, _) => {
ast::item_enum(enum_definition, _) => {
check_case(cx, it.ident, it.id, it.id, it.span);
for variants.each |variant| {
for enum_definition.variants.each |variant| {
check_case(cx, variant.node.name,
variant.node.id, it.id, variant.span);
}

View file

@ -973,13 +973,13 @@ class Resolver {
}
// These items live in both the type and value namespaces.
item_enum(variants, _) => {
item_enum(enum_definition, _) => {
let (name_bindings, new_parent) = self.add_child(atom, parent,
~[ValueNS, TypeNS], sp);
(*name_bindings).define_type(def_ty(local_def(item.id)), sp);
for variants.each |variant| {
for enum_definition.variants.each |variant| {
self.build_reduced_graph_for_variant(variant,
local_def(item.id),
new_parent,
@ -1146,10 +1146,10 @@ class Resolver {
variant.span);
self.structs.insert(local_def(variant.node.id), false);
}
enum_variant_kind(variants) => {
enum_variant_kind(enum_definition) => {
(*child).define_type(def_ty(local_def(variant.node.id)),
variant.span);
for variants.each |variant| {
for enum_definition.variants.each |variant| {
self.build_reduced_graph_for_variant(variant, item_id,
parent, visitor);
}

View file

@ -4912,11 +4912,11 @@ fn trans_class_dtor(ccx: @crate_ctxt, path: path,
lldecl
}
fn trans_variants(ccx: @crate_ctxt, variants: ~[ast::variant],
fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def,
id: ast::node_id, tps: ~[ast::ty_param], degen: bool,
path: @ast_map::path, vi: @~[ty::variant_info],
i: &mut uint) {
for vec::each(variants) |variant| {
for vec::each(enum_definition.variants) |variant| {
let disr_val = vi[*i].disr_val;
*i += 1;
@ -4933,8 +4933,9 @@ fn trans_variants(ccx: @crate_ctxt, variants: ~[ast::variant],
trans_struct_def(ccx, struct_def, tps, path,
variant.node.name, variant.node.id);
}
ast::enum_variant_kind(variants) => {
trans_variants(ccx, variants, id, tps, degen, path, vi, i);
ast::enum_variant_kind(enum_definition) => {
trans_enum_def(ccx, enum_definition, id, tps, degen, path, vi,
i);
}
}
}
@ -4976,13 +4977,13 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
ast::item_mod(m) => {
trans_mod(ccx, m);
}
ast::item_enum(variants, tps) => {
ast::item_enum(enum_definition, tps) => {
if tps.len() == 0u {
let degen = variants.len() == 1u;
let degen = enum_definition.variants.len() == 1u;
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
let mut i = 0;
trans_variants(ccx, variants, item.id, tps, degen, path, vi,
&mut i);
trans_enum_def(ccx, enum_definition, item.id, tps, degen, path,
vi, &mut i);
}
}
ast::item_const(_, expr) => consts::trans_const(ccx, expr, item.id),
@ -5317,12 +5318,12 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
let _icx = ccx.insn_ctxt(~"trans_constant");
match it.node {
ast::item_enum(variants, _) => {
ast::item_enum(enum_definition, _) => {
let vi = ty::enum_variants(ccx.tcx, {crate: ast::local_crate,
node: it.id});
let mut i = 0;
let path = item_path(ccx, it);
for vec::each(variants) |variant| {
for vec::each(enum_definition.variants) |variant| {
let p = vec::append(path, ~[path_name(variant.node.name),
path_name(@~"discrim")]);
let s = mangle_exported_name(ccx, p, ty::mk_int(ccx.tcx));

View file

@ -2837,7 +2837,9 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[variant_info] {
expr, since check_enum_variants also updates the enum_var_cache
*/
match cx.items.get(id.node) {
ast_map::node_item(@{node: ast::item_enum(variants, _), _}, _) => {
ast_map::node_item(@{node: ast::item_enum(enum_definition, _), _},
_) => {
let variants = enum_definition.variants;
let mut disr_val = -1;
@vec::map(variants, |variant| {
match variant.node.kind {

View file

@ -439,8 +439,8 @@ fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def,
fn check_item(ccx: @crate_ctxt, it: @ast::item) {
match it.node {
ast::item_const(_, e) => check_const(ccx, it.span, e, it.id),
ast::item_enum(vs, _) => {
check_enum_variants(ccx, it.span, vs, it.id);
ast::item_enum(enum_definition, _) => {
check_enum_variants(ccx, it.span, enum_definition.variants, it.id);
}
ast::item_fn(decl, tps, body) => {
check_bare_fn(ccx, decl, body, it.id, none);

View file

@ -135,8 +135,9 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) => {
result_ty = some(enum_ty);
}
ast::enum_variant_kind(variants) => {
get_enum_variant_types(ccx, enum_ty, variants, ty_params, rp);
ast::enum_variant_kind(enum_definition) => {
get_enum_variant_types(ccx, enum_ty, enum_definition.variants,
ty_params, rp);
result_ty = none;
}
};
@ -404,10 +405,11 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
match it.node {
// These don't define types.
ast::item_foreign_mod(_) | ast::item_mod(_) => {}
ast::item_enum(variants, ty_params) => {
ast::item_enum(enum_definition, ty_params) => {
let tpt = ty_of_item(ccx, it);
write_ty_to_tcx(tcx, it.id, tpt.ty);
get_enum_variant_types(ccx, tpt.ty, variants, ty_params, rp);
get_enum_variant_types(ccx, tpt.ty, enum_definition.variants,
ty_params, rp);
}
ast::item_impl(tps, trait_ref, selfty, ms) => {
let i_bounds = ty_param_bounds(ccx, tps);

View file

@ -146,10 +146,10 @@ fn fold_enum(
let desc = do astsrv::exec(srv) |ctxt| {
match check ctxt.ast_map.get(doc_id) {
ast_map::node_item(@{
node: ast::item_enum(ast_variants, _), _
node: ast::item_enum(enum_definition, _), _
}, _) => {
let ast_variant = option::get(
vec::find(ast_variants, |v| {
vec::find(enum_definition.variants, |v| {
*v.node.name == variant.name
}));

View file

@ -79,9 +79,9 @@ fn moddoc_from_mod(
constdoc_from_const(itemdoc)
))
}
ast::item_enum(variants, _) => {
ast::item_enum(enum_definition, _) => {
some(doc::enumtag(
enumdoc_from_enum(itemdoc, variants)
enumdoc_from_enum(itemdoc, enum_definition.variants)
))
}
ast::item_trait(_, _, methods) => {

View file

@ -111,10 +111,10 @@ fn fold_enum(
let sig = do astsrv::exec(srv) |ctxt| {
match check ctxt.ast_map.get(doc_id) {
ast_map::node_item(@{
node: ast::item_enum(ast_variants, _), _
node: ast::item_enum(enum_definition, _), _
}, _) => {
let ast_variant = option::get(
do vec::find(ast_variants) |v| {
do vec::find(enum_definition.variants) |v| {
*v.node.name == variant.name
});