about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-02-10 06:01:32 -0800
committerNiko Matsakis <niko@alum.mit.edu>2012-02-10 20:48:28 -0800
commitfdddf8f9e1d6738d42989a6d8a735dd58127e199 (patch)
tree9e324f85345957929daed40aedeaf52d0199b33d
parentdbcb54f4dc44957c9505958655a16e678ee4396b (diff)
downloadrust-fdddf8f9e1d6738d42989a6d8a735dd58127e199.tar.gz
rust-fdddf8f9e1d6738d42989a6d8a735dd58127e199.zip
put serializer into the build and encode full item paths
-rw-r--r--Makefile.in1
-rw-r--r--mk/tools.mk20
-rw-r--r--src/comp/metadata/common.rs7
-rw-r--r--src/comp/metadata/csearch.rs10
-rw-r--r--src/comp/metadata/decoder.rs30
-rw-r--r--src/comp/metadata/encoder.rs64
-rw-r--r--src/comp/middle/ast_map.rs14
-rw-r--r--src/comp/middle/ty.rs39
-rw-r--r--src/comp/util/ppaux.rs10
-rw-r--r--src/libcore/uint.rs23
-rw-r--r--src/libstd/ebml.rs18
-rwxr-xr-xsrc/serializer/serializerbin0 -> 294724 bytes
-rw-r--r--src/serializer/serializer.rs22
-rw-r--r--src/serializer/stest.rs9
-rwxr-xr-xsrc/test/run-pass/qquotebin0 -> 180592 bytes
15 files changed, 238 insertions, 29 deletions
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<int>], ty_params: [ty_param]) {
+                            id: node_id, variants: [variant],
+                            path: ast_map::path, &index: [entry<int>],
+                            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<int>]) {
+                        &index: [entry<int>], 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<int>] = [];
     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::<u8>(*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
--- /dev/null
+++ b/src/serializer/serializer
Binary files differdiff --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<int>;
 
+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
--- /dev/null
+++ b/src/test/run-pass/qquote
Binary files differ