diff --git a/Makefile.in b/Makefile.in index 4ee65d87e82..faee8e8d863 100644 --- a/Makefile.in +++ b/Makefile.in @@ -410,6 +410,7 @@ TSREQS := \ FUZZ := $(HBIN3_H_$(CFG_HOST_TRIPLE))/fuzzer$(X) CARGO := $(HBIN3_H_$(CFG_HOST_TRIPLE))/cargo$(X) RUSTDOC := $(HBIN3_H_$(CFG_HOST_TRIPLE))/rustdoc$(X) +SERIALIZER := $(HBIN3_H_$(CFG_HOST_TRIPLE))/serializer$(X) all: rustc $(GENERATED) docs $(FUZZ) $(CARGO) $(RUSTDOC) diff --git a/mk/tools.mk b/mk/tools.mk index 0f9ebc9d090..772de00f9c2 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -16,6 +16,11 @@ CARGO_INPUTS := $(wildcard $(S)src/cargo/*rs) RUSTDOC_CRATE := $(S)src/rustdoc/rustdoc.rc RUSTDOC_INPUTS := $(wildcard $(S)src/rustdoc/*.rs) +# Serializer, generates serialization code +# (Should eventually move into a compiler ext) +SERIALIZER_CRATE := $(S)src/serializer/serializer.rc +SERIALIZER_INPUTS := $(wildcard $(S)src/serializer/*.rs) + # FIXME: These are only built for the host arch. Eventually we'll # have tools that need to built for other targets. define TOOLS_STAGE_N @@ -83,6 +88,21 @@ $$(HBIN$(2)_H_$(4))/rustdoc$$(X): \ @$$(call E, cp: $$@) $$(Q)cp $$< $$@ +$$(TBIN$(1)_T_$(4)_H_$(3))/serializer$$(X): \ + $$(SERIALIZER_CRATE) $$(SERIALIZER_INPUTS) \ + $$(TSREQ$(1)_T_$(4)_H_$(3)) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTC) + @$$(call E, compile_and_link: $$@) + $$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< + +$$(HBIN$(2)_H_$(4))/serializer$$(X): \ + $$(TBIN$(1)_T_$(4)_H_$(3))/serializer$$(X) \ + $$(HSREQ$(2)_$(4)) + @$$(call E, cp: $$@) + $$(Q)cp $$< $$@ + endef $(foreach host,$(CFG_TARGET_TRIPLES), \ diff --git a/src/comp/metadata/common.rs b/src/comp/metadata/common.rs index f638dfecf1f..32358794212 100644 --- a/src/comp/metadata/common.rs +++ b/src/comp/metadata/common.rs @@ -70,6 +70,13 @@ const tag_impl_iface: uint = 0x32u; // discriminator value for variants const tag_disr_val: uint = 0x34u; +// used to encode ast_map::path and ast_map::path_elt +const tag_path: uint = 0x40u; +const tag_path_len: uint = 0x41u; +const tag_path_elt_mod: uint = 0x42u; +const tag_path_elt_name: uint = 0x43u; + + // djb's cdb hashes. fn hash_node_id(&&node_id: int) -> uint { ret 177573u ^ (node_id as uint); } diff --git a/src/comp/metadata/csearch.rs b/src/comp/metadata/csearch.rs index 7d5ae7048b8..1ac86faed0d 100644 --- a/src/comp/metadata/csearch.rs +++ b/src/comp/metadata/csearch.rs @@ -2,7 +2,8 @@ import syntax::ast; import syntax::ast_util; -import middle::ty; +import middle::{ty, ast_map}; +import option::{some, none}; import driver::session; export get_symbol; @@ -13,6 +14,7 @@ export get_impls_for_mod; export get_iface_methods; export get_type; export get_impl_iface; +export get_item_path; fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> str { let cdata = cstore::get_crate_data(cstore, def.crate).data; @@ -55,6 +57,12 @@ fn resolve_path(cstore: cstore::cstore, cnum: ast::crate_num, ret result; } +fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path { + let cstore = tcx.sess.cstore; + let cdata = cstore::get_crate_data(cstore, def.crate); + ret decoder::get_item_path(cdata, def.node); +} + fn get_enum_variants(tcx: ty::ctxt, def: ast::def_id) -> [ty::variant_info] { let cstore = tcx.sess.cstore; let cdata = cstore::get_crate_data(cstore, def.crate); diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index 163522ea4c7..ccc0e3bfa2a 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -6,6 +6,7 @@ import syntax::{ast, ast_util}; import driver::session::session; import front::attr; import middle::ty; +import middle::ast_map; import common::*; import tydecode::{parse_ty_data, parse_def_id, parse_bounds_data}; import syntax::print::pprust; @@ -28,6 +29,7 @@ export get_crate_hash; export get_impls_for_mod; export get_iface_methods; export get_crate_module_paths; +export get_item_path; // A function that takes a def_id relative to the crate being searched and // returns a def_id relative to the compilation environment, i.e. if we hit a @@ -176,6 +178,30 @@ fn resolve_path(path: [ast::ident], data: @[u8]) -> [ast::def_id] { ret result; } +fn item_path(item_doc: ebml::doc) -> ast_map::path { + let path_doc = ebml::get_doc(item_doc, tag_path); + + let len_doc = ebml::get_doc(path_doc, tag_path_len); + let len = ebml::doc_as_uint(len_doc); + + let result = []; + vec::reserve(result, len); + + ebml::docs(path_doc) {|tag, elt_doc| + if tag == tag_path_elt_mod { + let str = ebml::doc_str(elt_doc); + result += [ast_map::path_mod(str)]; + } else if tag == tag_path_elt_name { + let str = ebml::doc_str(elt_doc); + result += [ast_map::path_name(str)]; + } else { + // ignore tag_path_len element + } + } + + ret result; +} + fn item_name(item: ebml::doc) -> ast::ident { let name = ebml::get_doc(item, tag_paths_data_name); str::from_bytes(ebml::doc_data(name)) @@ -234,6 +260,10 @@ fn get_symbol(data: @[u8], id: ast::node_id) -> str { ret item_symbol(lookup_item(id, data)); } +fn get_item_path(cdata: cmd, id: ast::node_id) -> ast_map::path { + item_path(lookup_item(id, cdata.data)) +} + fn get_enum_variants(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> [ty::variant_info] { let data = cdata.data; diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index 9395558332f..89b188f92a4 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -10,6 +10,7 @@ import common::*; import middle::trans::common::crate_ctxt; import middle::ty; import middle::ty::node_id_to_type; +import middle::ast_map; import front::attr; import driver::session::session; @@ -233,8 +234,9 @@ fn encode_enum_id(ebml_w: ebml::writer, id: def_id) { } fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer, - id: node_id, variants: [variant], - &index: [entry], ty_params: [ty_param]) { + id: node_id, variants: [variant], + path: ast_map::path, &index: [entry], + ty_params: [ty_param]) { let disr_val = 0; let i = 0; let vi = ty::enum_variants(ecx.ccx.tcx, {crate: local_crate, node: id}); @@ -256,14 +258,38 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer, disr_val = vi[i].disr_val; } encode_type_param_bounds(ebml_w, ecx, ty_params); + encode_path(ebml_w, path, ast_map::path_name(variant.node.name)); ebml::end_tag(ebml_w); disr_val += 1; i += 1; } } +fn encode_path(ebml_w: ebml::writer, + path: ast_map::path, + name: ast_map::path_elt) { + fn encode_path_elt(ebml_w: ebml::writer, elt: ast_map::path_elt) { + let (tag, name) = alt elt { + ast_map::path_mod(name) { (tag_path_elt_mod, name) } + ast_map::path_name(name) { (tag_path_elt_name, name) } + }; + + ebml_w.wr_tag(tag) {|| + ebml_w.wr_str(name) + } + } + + ebml_w.wr_tag(tag_path) {|| + ebml_w.wr_tag(tag_path_len) {|| + ebml_w.wr_uint(vec::len(path) + 1u); + } + vec::iter(path) {|pe| encode_path_elt(ebml_w, pe); } + encode_path_elt(ebml_w, name); + } +} + fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod, - id: node_id, name: ident) { + id: node_id, path: ast_map::path, name: ident) { ebml::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(id)); encode_family(ebml_w, 'm' as u8); @@ -281,11 +307,12 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod, _ { ecx.ccx.tcx.sess.bug("encode_info_for_mod: \ undocumented invariant"); } } + encode_path(ebml_w, path, ast_map::path_mod(name)); ebml::end_tag(ebml_w); } fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, - &index: [entry]) { + &index: [entry], path: ast_map::path) { let tcx = ecx.ccx.tcx; alt item.node { item_const(_, _) { @@ -294,6 +321,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_family(ebml_w, 'c' as u8); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_symbol(ecx, ebml_w, item.id); + encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml::end_tag(ebml_w); } item_fn(decl, tps, _) { @@ -308,16 +336,18 @@ 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_symbol(ecx, ebml_w, item.id); + encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml::end_tag(ebml_w); } item_mod(m) { - encode_info_for_mod(ecx, ebml_w, m, item.id, item.ident); + encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident); } item_native_mod(_) { ebml::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); encode_family(ebml_w, 'n' as u8); encode_name(ebml_w, item.ident); + encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml::end_tag(ebml_w); } item_ty(_, tps) { @@ -327,6 +357,7 @@ 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); + encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml::end_tag(ebml_w); } item_enum(variants, tps) { @@ -339,8 +370,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, for v: variant in variants { encode_variant_id(ebml_w, local_def(v.node.id)); } + encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml::end_tag(ebml_w); - encode_enum_variant_info(ecx, ebml_w, item.id, variants, index, tps); + encode_enum_variant_info(ecx, ebml_w, item.id, variants, + path, index, tps); } item_class(_,_,_,_,_) { fail "encode: implement item_class"; @@ -355,6 +388,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_type(ecx, ebml_w, ty::ty_fn_ret(fn_ty)); encode_name(ebml_w, item.ident); encode_symbol(ecx, ebml_w, item.id); + encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml::end_tag(ebml_w); index += [{val: ctor_id, pos: ebml_w.writer.tell()}]; @@ -364,6 +398,7 @@ 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, fn_ty); encode_symbol(ecx, ebml_w, ctor_id); + encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml::end_tag(ebml_w); } item_impl(tps, ifce, _, methods) { @@ -388,8 +423,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, } _ {} } + encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml::end_tag(ebml_w); + let impl_path = path + [ast_map::path_name(item.ident)]; for m in methods { index += [{val: m.id, pos: ebml_w.writer.tell()}]; ebml::start_tag(ebml_w, tag_items_data_item); @@ -400,6 +437,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, node_id_to_type(tcx, m.id)); encode_name(ebml_w, m.ident); encode_symbol(ecx, ebml_w, m.id); + encode_path(ebml_w, impl_path, ast_map::path_name(m.ident)); ebml::end_tag(ebml_w); } } @@ -419,13 +457,14 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, ebml::end_tag(ebml_w); i += 1u; } + encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml::end_tag(ebml_w); } } } fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer, - nitem: @native_item) { + nitem: @native_item, path: ast_map::path) { ebml::start_tag(ebml_w, tag_items_data_item); alt nitem.node { native_item_fn(fn_decl, tps) { @@ -439,6 +478,7 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer, encode_type_param_bounds(ebml_w, ecx, tps); encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, nitem.id)); encode_symbol(ecx, ebml_w, nitem.id); + encode_path(ebml_w, path, ast_map::path_name(nitem.ident)); } } ebml::end_tag(ebml_w); @@ -449,16 +489,16 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer, let index: [entry] = []; ebml::start_tag(ebml_w, tag_items_data); index += [{val: crate_node_id, pos: ebml_w.writer.tell()}]; - encode_info_for_mod(ecx, ebml_w, crate_mod, crate_node_id, ""); + encode_info_for_mod(ecx, ebml_w, crate_mod, crate_node_id, [], ""); ecx.ccx.ast_map.items {|key, val| alt val { - middle::ast_map::node_item(i, _) { + middle::ast_map::node_item(i, path) { index += [{val: key, pos: ebml_w.writer.tell()}]; - encode_info_for_item(ecx, ebml_w, i, index); + encode_info_for_item(ecx, ebml_w, i, index, *path); } - middle::ast_map::node_native_item(i, _) { + middle::ast_map::node_native_item(i, path) { index += [{val: key, pos: ebml_w.writer.tell()}]; - encode_info_for_native_item(ecx, ebml_w, i); + encode_info_for_native_item(ecx, ebml_w, i, *path); } _ { } } diff --git a/src/comp/middle/ast_map.rs b/src/comp/middle/ast_map.rs index ca3885d89d7..1504f5f738e 100644 --- a/src/comp/middle/ast_map.rs +++ b/src/comp/middle/ast_map.rs @@ -6,6 +6,20 @@ import syntax::{visit, codemap}; enum path_elt { path_mod(str), path_name(str) } type path = [path_elt]; +fn path_to_str_with_sep(p: path, sep: str) -> str { + let strs = vec::map(p) {|e| + alt e { + path_mod(s) { s } + path_name(s) { s } + } + }; + str::connect(strs, sep) +} + +fn path_to_str(p: path) -> str { + path_to_str_with_sep(p, "::") +} + enum ast_node { node_item(@item, @path), node_native_item(@native_item, @path), diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 5c6e956508f..019ba856e98 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -128,6 +128,7 @@ export ck_uniq; export param_bound, param_bounds, bound_copy, bound_send, bound_iface; export param_bounds_to_kind; export default_arg_mode_for_ty; +export item_path; // Data types @@ -2371,6 +2372,44 @@ fn substd_enum_variants(cx: ctxt, id: ast::def_id, tps: [ty::t]) } } +fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path { + if id.crate != ast::local_crate { + csearch::get_item_path(cx, id) + } else { + let node = cx.items.get(id.node); + alt node { + ast_map::node_item(item, path) { + let item_elt = alt item.node { + item_mod(_) | item_native_mod(_) { + ast_map::path_mod(item.ident) + } + _ { + ast_map::path_name(item.ident) + } + }; + *path + [item_elt] + } + + ast_map::node_native_item(nitem, path) { + *path + [ast_map::path_name(nitem.ident)] + } + + ast_map::node_method(method, path) { + *path + [ast_map::path_name(method.ident)] + } + + ast_map::node_variant(variant, _, path) { + vec::init(*path) + [ast_map::path_name(variant.node.name)] + } + + ast_map::node_expr(_) | ast_map::node_arg(_, _) | + ast_map::node_local(_) | ast_map::node_res_ctor(_) { + cx.sess.bug(#fmt["cannot find item_path for node %?", node]); + } + } + } +} + fn enum_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] { alt cx.enum_var_cache.find(id) { some(variants) { ret variants; } diff --git a/src/comp/util/ppaux.rs b/src/comp/util/ppaux.rs index 985c710c659..24337878a5c 100644 --- a/src/comp/util/ppaux.rs +++ b/src/comp/util/ppaux.rs @@ -110,6 +110,16 @@ fn ty_to_str(cx: ctxt, typ: t) -> str { ty_param(id, _) { "'" + str::from_bytes([('a' as u8) + (id as u8)]) } + ty_enum(did, tps) { + let path = ty::item_path(cx, did); + let base = ast_map::path_to_str(path); + if vec::is_empty(tps) { + base + } else { + let tps_strs = vec::map(tps) {|t| ty_to_str(cx, t) }; + #fmt["%s<%s>", base, str::connect(tps_strs, ",")] + } + } _ { ty_to_short_str(cx, typ) } } } diff --git a/src/libcore/uint.rs b/src/libcore/uint.rs index 2112399ba80..5799211865f 100644 --- a/src/libcore/uint.rs +++ b/src/libcore/uint.rs @@ -20,6 +20,20 @@ This is 2^wordsize - 1 */ const max_value: uint = 0u - 1u; +/* +Function: max +*/ +fn max(x: uint, y: uint) -> uint { + if x > y { x } else { y } +} + +/* +Function: min +*/ +fn min(x: uint, y: uint) -> uint { + if x < y { x } else { y } +} + /* Function: add */ pure fn add(x: uint, y: uint) -> uint { ret x + y; } @@ -252,6 +266,15 @@ Convert to a string */ fn str(i: uint) -> str { ret to_str(i, 10u); } +/* +Function: compl + +Computes the bitwise complement. +*/ +fn compl(i: uint) -> uint { + uint::max_value ^ i +} + #[cfg(test)] mod tests { diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index c4b07086acd..bee73814580 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -97,6 +97,8 @@ fn tagged_docs(d: doc, tg: uint, it: fn(doc)) { fn doc_data(d: doc) -> [u8] { ret vec::slice::(*d.data, d.start, d.end); } +fn doc_str(d: doc) -> str { ret str::from_bytes(doc_data(d)); } + fn be_uint_from_bytes(data: @[u8], start: uint, size: uint) -> uint { let sz = size; assert (sz <= 4u); @@ -136,11 +138,11 @@ fn write_sized_vint(w: io::writer, n: uint, size: uint) { w.write(buf); } -fn write_vint(w: io::writer, n: uint) { - if n < 0x7fu { write_sized_vint(w, n, 1u); ret; } - if n < 0x4000u { write_sized_vint(w, n, 2u); ret; } - if n < 0x200000u { write_sized_vint(w, n, 3u); ret; } - if n < 0x10000000u { write_sized_vint(w, n, 4u); ret; } +fn write_vint(w: io::writer, n: u64) { + if n < 0x7f_u64 { write_sized_vint(w, n, 1u); ret; } + if n < 0x4000_u64 { write_sized_vint(w, n, 2u); ret; } + if n < 0x200000_u64 { write_sized_vint(w, n, 3u); ret; } + if n < 0x10000000_u64 { write_sized_vint(w, n, 4u); ret; } #error("vint to write too big"); fail; } @@ -177,7 +179,11 @@ impl writer_util for writer { end_tag(self); } - fn wr_uint(id: uint) { + fn wr_uint(id: u64) { + write_vint(self.writer, id); + } + + fn wr_int(id: uint) { write_vint(self.writer, id); } diff --git a/src/serializer/serializer b/src/serializer/serializer new file mode 100755 index 00000000000..50ff84ee0bc Binary files /dev/null and b/src/serializer/serializer differ diff --git a/src/serializer/serializer.rs b/src/serializer/serializer.rs index f8c4349a7ce..80b51ba78a7 100644 --- a/src/serializer/serializer.rs +++ b/src/serializer/serializer.rs @@ -106,12 +106,8 @@ impl serialize_ctx for serialize_ctx { ret tps_map; } - fn path(mod_: [str], id: str) -> str { - str::connect(mod_ + [id], "::") - } - - fn ident(mod_: [str], id: str) -> str { - str::connect(mod_ + [id], "_") + fn ident(base_path: ast_map::path, id: str) -> str { + #fmt["%s_%s", ast_map::path_to_str_with_sep(base_path, "_"), id] } fn instantiate(id: ast::def_id, args: [ty::t]) -> ty::t { @@ -134,7 +130,11 @@ impl serialize_ctx for serialize_ctx { } fn blk(stmts: [ast_stmt]) -> ast_blk { - "{" + str::connect(stmts, ";") + "}" + if vec::is_empty(stmts) { + "" + } else { + "{" + str::connect(stmts, ";") + "}" + } } fn blk_expr(stmts: [ast_stmt]) -> ast_expr { @@ -159,6 +159,7 @@ impl serialize_ctx for serialize_ctx { // in case of recursive calls: let id = self.tyfns.size(); let ty0_str = ppaux::ty_to_str(self.tcx, ty0); + #debug["ty0_str = %s / ty0 = %?", ty0_str, ty0]; let name = #fmt["serialize_%u /*%s*/", id, ty0_str]; self.tyfns.insert(ty0, name); let v = "v"; @@ -221,11 +222,11 @@ impl serialize_ctx for serialize_ctx { fn serialize_enum(v: ast_expr, id: ast::def_id, tps: [ty::t]) -> ast_expr { - let path = []; let variants = ty::substd_enum_variants(self.tcx, id, tps); let arms = vec::map(variants) {|variant| - let v_path = self.path(path, variant.name); + let item_path = ty::item_path(self.tcx, variant.id); + let v_path = ast_map::path_to_str(item_path); let n_args = vec::len(variant.args); let (v_pat, stmts) = { if n_args == 0u { @@ -235,7 +236,8 @@ impl serialize_ctx for serialize_ctx { } }; - let v_const = #fmt["at_%s", self.ident(path, variant.name)]; + let v_ident = ast_map::path_to_str_with_sep(item_path, "_"); + let v_const = #fmt["at_%s", v_ident]; #fmt["%s { \ start_variant(cx, %s); \ diff --git a/src/serializer/stest.rs b/src/serializer/stest.rs index c7161e07a27..b1d255f4939 100644 --- a/src/serializer/stest.rs +++ b/src/serializer/stest.rs @@ -28,4 +28,13 @@ type test5 = { type test6 = option; +mod test7 { + enum testa { + } + + enum testb { + t4_a(@testa), t4_b(@testb) + } +} + fn main() {} \ No newline at end of file diff --git a/src/test/run-pass/qquote b/src/test/run-pass/qquote new file mode 100755 index 00000000000..0c4c440cafa Binary files /dev/null and b/src/test/run-pass/qquote differ