diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index c076b044f52b..ace34b79a0c2 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -246,6 +246,7 @@ fn get_tag_variants(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) for did: ast::def_id in variant_ids { let item = find_item(did.node, items); let ctor_ty = item_type(item, tcx, cdata); + let name = item_name(item); let arg_tys: [ty::t] = []; alt ty::struct(tcx, ctor_ty) { ty::ty_fn(f) { @@ -257,8 +258,8 @@ fn get_tag_variants(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) some(val) { disr_val = val; } _ { /* empty */ } } - infos += [@{args: arg_tys, ctor_ty: ctor_ty, id: did, - disr_val: disr_val}]; + infos += [@{args: arg_tys, ctor_ty: ctor_ty, name: name, + id: did, disr_val: disr_val}]; disr_val += 1; } ret infos; diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index 41235c01d3dc..1a0a6cfef908 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -239,6 +239,7 @@ fn encode_tag_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer, ebml::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(variant.node.id)); encode_family(ebml_w, 'v' as u8); + encode_name(ebml_w, variant.node.name); encode_tag_id(ebml_w, local_def(id)); encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, variant.node.id)); diff --git a/src/comp/middle/shape.rs b/src/comp/middle/shape.rs index b867bd67b8f1..8e49aeaa0803 100644 --- a/src/comp/middle/shape.rs +++ b/src/comp/middle/shape.rs @@ -458,6 +458,15 @@ fn shape_of_variant(ccx: @crate_ctxt, v: ty::variant_info, ret s; } +//fn variant_names(ccx: @crate_ctxt, tag_id: ast::def_id) -> [str] { +// assert ast::local_crate == tag_id.crate; +// alt ccx.tcx.items.get(tag_id.node) { +// ast_map::node_item(@{node: ast::item_tag(variants, _), _}) { +// vec::map(variants) {|variant| variant.node.name} +// } +// } +//} + fn gen_tag_shapes(ccx: @crate_ctxt) -> ValueRef { // Loop over all the tag variants and write their shapes into a data // buffer. As we do this, it's possible for us to discover new tags, so we @@ -471,11 +480,14 @@ fn gen_tag_shapes(ccx: @crate_ctxt) -> ValueRef { let item_tyt = ty::lookup_item_type(ccx.tcx, did); let ty_param_count = vec::len(*item_tyt.bounds); - for v: ty::variant_info in *variants { + vec::iter(*variants) {|v| offsets += [vec::len(data) as u16]; let variant_shape = shape_of_variant(ccx, v, ty_param_count); add_substr(data, variant_shape); + + let zname = str::bytes(v.name) + [0u8]; + add_substr(data, zname); } i += 1u; diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 59fd826791a3..18ec1e86f3ec 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -2633,8 +2633,8 @@ fn impl_iface(cx: ctxt, id: ast::def_id) -> option::t { } // Tag information -type variant_info = @{args: [ty::t], ctor_ty: ty::t, id: ast::def_id, - disr_val: int}; +type variant_info = @{args: [ty::t], ctor_ty: ty::t, name: str, + id: ast::def_id, disr_val: int}; fn tag_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] { alt cx.tag_var_cache.find(id) { @@ -2666,6 +2666,7 @@ fn tag_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] { } @{args: arg_tys, ctor_ty: ctor_ty, + name: variant.node.name, id: ast_util::local_def(variant.node.id), disr_val: disr_val } diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp index 961cfe7bc461..37d8a42e95a1 100644 --- a/src/rt/rust_shape.cpp +++ b/src/rt/rust_shape.cpp @@ -358,7 +358,8 @@ public: void walk_res2(const rust_fn *dtor, uint16_t n_ty_params, const type_param *ty_params_sp, const uint8_t *end_sp, const data_pair &live); - void walk_variant2(tag_info &tinfo, tag_variant_t variant_id, + void walk_variant2(tag_info &tinfo, + tag_variant_t variant_id, const std::pair variant_ptr_and_end); @@ -413,7 +414,8 @@ cmp::walk_res2(const rust_fn *dtor, uint16_t n_ty_params, } void -cmp::walk_variant2(tag_info &tinfo, tag_variant_t variant_id, +cmp::walk_variant2(tag_info &tinfo, + tag_variant_t variant_id, const std::pair variant_ptr_and_end) { cmp sub(*this, variant_ptr_and_end.first, tinfo.params); @@ -485,7 +487,8 @@ log::walk_vec2(bool is_pod, const std::pair &data) { } void -log::walk_variant2(tag_info &tinfo, tag_variant_t variant_id, +log::walk_variant2(tag_info &tinfo, + tag_variant_t variant_id, const std::pair variant_ptr_and_end) { log sub(*this, variant_ptr_and_end.first, tinfo.params); diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h index 41cc9c11fb37..848e304df302 100644 --- a/src/rt/rust_shape.h +++ b/src/rt/rust_shape.h @@ -246,6 +246,9 @@ public: std::pair get_variant_sp(tag_info &info, tag_variant_t variant_id); + const char * + get_variant_name(tag_info &info, tag_variant_t variant_id); + protected: inline uint8_t peek() { return *sp; } @@ -415,9 +418,19 @@ ctxt::get_variant_sp(tag_info &tinfo, tag_variant_t variant_id) { const uint8_t *variant_ptr = tables->tags + variant_offset; uint16_t variant_len = get_u16_bump(variant_ptr); const uint8_t *variant_end = variant_ptr + variant_len; + return std::make_pair(variant_ptr, variant_end); } +template +const char * +ctxt::get_variant_name(tag_info &tinfo, tag_variant_t variant_id) { + std::pair variant_ptr_and_end = + this->get_variant_sp(tinfo, variant_id); + // skip over the length to get the null-terminated string: + return (const char*)(variant_ptr_and_end.second + 2); +} + template void ctxt::walk_vec0() { @@ -951,7 +964,7 @@ template void data::walk_variant1(tag_info &tinfo, tag_variant_t variant_id) { std::pair variant_ptr_and_end = - this->get_variant_sp(tinfo, variant_id); + this->get_variant_sp(tinfo, variant_id); static_cast(this)->walk_variant2(tinfo, variant_id, variant_ptr_and_end); } @@ -1128,7 +1141,8 @@ private: } void walk_tag2(tag_info &tinfo, tag_variant_t tag_variant) { - out << prefix << "tag" << tag_variant; + // out << prefix << "tag" << tag_variant; + out << prefix << get_variant_name(tinfo, tag_variant); data::walk_variant1(tinfo, tag_variant); } @@ -1187,9 +1201,10 @@ private: void walk_struct2(const uint8_t *end_sp); void walk_vec2(bool is_pod, const std::pair &data); - void walk_variant2(tag_info &tinfo, tag_variant_t variant_id, - const std::pair - variant_ptr_and_end); + void walk_variant2(tag_info &tinfo, + tag_variant_t variant_id, + const std::pair + variant_ptr_and_end); void walk_string2(const std::pair &data); void walk_res2(const rust_fn *dtor, unsigned n_params, const type_param *params, const uint8_t *end_sp, bool live); diff --git a/src/test/run-pass/log-knows-the-names-of-variants-in-std.rs b/src/test/run-pass/log-knows-the-names-of-variants-in-std.rs new file mode 100644 index 000000000000..1ac1e0e3ef56 --- /dev/null +++ b/src/test/run-pass/log-knows-the-names-of-variants-in-std.rs @@ -0,0 +1,18 @@ +use std; +import std::list; + +tag foo { + a(uint); + b(str); +} + +fn check_log(exp: str, v: T) { + assert exp == #fmt["%?", v]; +} + +fn main() { + let x = list::from_vec([a(22u), b("hi")]); + let exp = "cons(a(22), @cons(b(\"hi\"), @nil))"; + assert #fmt["%?", x] == exp; + check_log(exp, x); +} diff --git a/src/test/run-pass/log-knows-the-names-of-variants.rs b/src/test/run-pass/log-knows-the-names-of-variants.rs new file mode 100644 index 000000000000..ac8e368540ca --- /dev/null +++ b/src/test/run-pass/log-knows-the-names-of-variants.rs @@ -0,0 +1,11 @@ +tag foo { + a(uint); + b(str); + c; +} + +fn main() { + assert "a(22)" == #fmt["%?", a(22u)]; + assert "b(\"hi\")" == #fmt["%?", b("hi")]; + assert "c" == #fmt["%?", c]; +}