From d91742294f282a07b1e26d8da02f7ecec4e0b952 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 12 Mar 2012 10:19:35 -0700 Subject: first (functional) version of the auto_serialize syntax ext --- src/rustc/driver/driver.rs | 13 +- src/rustc/metadata/astencode.rs | 29 ++-- src/rustc/middle/typeck.rs | 3 + src/rustc/syntax/ext/auto_serialize.rs | 269 ++++++++++++++++++++------------- src/rustc/syntax/ext/base.rs | 2 + src/rustc/syntax/ext/qquote.rs | 1 + 6 files changed, 193 insertions(+), 124 deletions(-) (limited to 'src/rustc') diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index dbdd5325e1a..71f39a77e36 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -15,7 +15,8 @@ import io::{reader_util, writer_util}; import getopts::{optopt, optmulti, optflag, optflagopt, opt_present}; import back::{x86, x86_64}; -enum pp_mode { ppm_normal, ppm_expanded, ppm_typed, ppm_identified, } +enum pp_mode {ppm_normal, ppm_expanded, ppm_typed, ppm_identified, + ppm_expanded_identified } fn default_configuration(sess: session, argv0: str, input: str) -> ast::crate_cfg { @@ -253,7 +254,7 @@ fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str, // from stdin, we're going to just suck the source into a string // so both the parser and pretty-printer can use it. let upto = alt ppm { - ppm_expanded { cu_expand } + ppm_expanded | ppm_expanded_identified { cu_expand } ppm_typed { cu_typeck } _ { cu_parse } }; @@ -265,7 +266,7 @@ fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str, ann = {pre: ann_paren_for_expr, post: bind ann_typed_post(option::get(tcx), _)}; } - ppm_identified { + ppm_identified | ppm_expanded_identified { ann = {pre: ann_paren_for_expr, post: ann_identified_post}; } ppm_expanded | ppm_normal {} @@ -498,7 +499,11 @@ fn parse_pretty(sess: session, &&name: str) -> pp_mode { ret ppm_expanded; } else if str::eq(name, "typed") { ret ppm_typed; - } else if str::eq(name, "identified") { ret ppm_identified; } + } else if str::eq(name, "expanded,identified") { + ret ppm_expanded_identified; + } else if str::eq(name, "identified") { + ret ppm_identified; + } sess.fatal("argument to `pretty` must be one of `normal`, `typed`, or " + "`identified`"); } diff --git a/src/rustc/metadata/astencode.rs b/src/rustc/metadata/astencode.rs index d9469184d6b..f09b4f902fd 100644 --- a/src/rustc/metadata/astencode.rs +++ b/src/rustc/metadata/astencode.rs @@ -6,12 +6,13 @@ import syntax::ast_util::inlined_item_methods; import syntax::codemap::span; import std::ebml; import std::ebml::writer; +import std::ebml::serializer; +import std::ebml::deserializer; import std::map::hashmap; -import std::serialization; -import std::serialization::serializer; -import std::serialization::deserializer; -import std::serialization::serializer_helpers; -import std::serialization::deserializer_helpers; +import serialization::serializer; +import serialization::deserializer; +import serialization::serializer_helpers; +import serialization::deserializer_helpers; import std::smallintmap::map; import middle::trans::common::maps; import middle::{ty, typeck, last_use, ast_map}; @@ -243,7 +244,7 @@ fn encode_id_range(ebml_w: ebml::writer, id_range: id_range) { fn decode_id_range(par_doc: ebml::doc) -> id_range { let range_doc = par_doc[c::tag_id_range]; - let dsr = serialization::ebml_deserializer(range_doc); + let dsr = ebml::ebml_deserializer(range_doc); dsr.read_tup(2u) {|| {min: dsr.read_tup_elt(0u) {|| dsr.read_int() }, max: dsr.read_tup_elt(1u) {|| dsr.read_int() }} @@ -368,7 +369,7 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item { fn decode_ast(par_doc: ebml::doc) -> ast::inlined_item { let chi_doc = par_doc[c::tag_tree]; - let d = serialization::ebml_deserializer(chi_doc); + let d = ebml::ebml_deserializer(chi_doc); astencode_gen::deserialize_syntax_ast_inlined_item(d) } @@ -398,7 +399,7 @@ fn encode_def(ebml_w: ebml::writer, def: ast::def) { } fn decode_def(xcx: extended_decode_ctxt, doc: ebml::doc) -> ast::def { - let dsr = serialization::ebml_deserializer(doc); + let dsr = ebml::ebml_deserializer(doc); let def = astencode_gen::deserialize_syntax_ast_def(dsr); def.tr(xcx) } @@ -445,7 +446,7 @@ fn encode_freevar_entry(ebml_w: ebml::writer, fv: freevar_entry) { astencode_gen::serialize_middle_freevars_freevar_entry(ebml_w, fv) } -impl helper for serialization::ebml_deserializer { +impl helper for ebml::ebml_deserializer { fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry { let fv = astencode_gen::deserialize_middle_freevars_freevar_entry(self); @@ -466,7 +467,7 @@ fn encode_method_origin(ebml_w: ebml::writer, mo: method_origin) { astencode_gen::serialize_middle_typeck_method_origin(ebml_w, mo) } -impl helper for serialization::ebml_deserializer { +impl helper for ebml::ebml_deserializer { fn read_method_origin(xcx: extended_decode_ctxt) -> method_origin { let fv = astencode_gen::deserialize_middle_typeck_method_origin(self); fv.tr(xcx) @@ -559,7 +560,7 @@ fn encode_dict_origin(ecx: @e::encode_ctxt, } -impl helpers for serialization::ebml_deserializer { +impl helpers for ebml::ebml_deserializer { fn read_dict_res(xcx: extended_decode_ctxt) -> typeck::dict_res { @self.read_to_vec {|| self.read_dict_origin(xcx) } } @@ -800,7 +801,7 @@ impl decoder for ebml::doc { } } -impl decoder for serialization::ebml_deserializer { +impl decoder for ebml::ebml_deserializer { fn read_ty(xcx: extended_decode_ctxt) -> ty::t { tydecode::parse_ty_data( self.parent.data, xcx.dcx.cdata.cnum, self.pos, xcx.dcx.tcx, @@ -850,7 +851,7 @@ fn decode_side_tables(xcx: extended_decode_ctxt, dcx.maps.copy_map.insert(id, ()); } else { let val_doc = entry_doc[c::tag_table_val]; - let val_dsr = serialization::ebml_deserializer(val_doc); + let val_dsr = ebml::ebml_deserializer(val_doc); if tag == (c::tag_table_def as uint) { let def = decode_def(xcx, val_doc); dcx.tcx.def_map.insert(id, def); @@ -903,7 +904,7 @@ fn encode_item_ast(ebml_w: ebml::writer, item: @ast::item) { #[cfg(test)] fn decode_item_ast(par_doc: ebml::doc) -> @ast::item { let chi_doc = par_doc[c::tag_tree]; - let d = serialization::ebml_deserializer(chi_doc); + let d = ebml::ebml_deserializer(chi_doc); @astencode_gen::deserialize_syntax_ast_item(d) } diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 1a6953d2d93..a61c88cad4a 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -306,6 +306,9 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t { for ast_ty: @ast::ty in args { param_bindings += [do_ast_ty_to_ty(tcx, use_site, mode, ast_ty)]; } + #debug("substituting(%s into %s)", + str::concat(vec::map(param_bindings, {|t| ty_to_str(tcx, t)})), + ty_to_str(tcx, ty_param_bounds_and_ty.ty)); let typ = ty::substitute_type_params(tcx, param_bindings, ty_param_bounds_and_ty.ty); diff --git a/src/rustc/syntax/ext/auto_serialize.rs b/src/rustc/syntax/ext/auto_serialize.rs index 5f1fa8cb379..b06bf81e5a7 100644 --- a/src/rustc/syntax/ext/auto_serialize.rs +++ b/src/rustc/syntax/ext/auto_serialize.rs @@ -82,26 +82,39 @@ import base::*; import driver::session::session; import codemap::span; import std::map; +import std::map::hashmap; +import front::attr; -export expand_auto_serialize; +export expand; -enum ser_cx = { +enum ser_cx = @{ ext_cx: ext_ctxt, - tps: map::map [@ast::stmt]> + tps: map::hashmap [@ast::stmt]> }; -fn expand_auto_serialize(cx: ext_ctxt, - span: span, - _mitem: ast::meta_item, - in_items: [@ast::item]) -> [@ast::item] { +fn expand(cx: ext_ctxt, + span: span, + _mitem: ast::meta_item, + in_items: [@ast::item]) -> [@ast::item] { + fn not_auto_serialize(a: ast::attribute) -> bool { + attr::get_attr_name(a) != "auto_serialize" + } + + fn filter_attrs(item: @ast::item) -> @ast::item { + @{attrs: vec::filter(item.attrs, not_auto_serialize) + with *item} + } + vec::flat_map(in_items) {|in_item| alt in_item.node { ast::item_ty(ty, tps) { - [in_item, ty_module(cx, in_item.ident, copy ty, tps)] + [filter_attrs(in_item), + ty_module(cx, in_item.ident, ty, tps)] } ast::item_enum(variants, tps) { - [in_item, enum_module(cx, in_item.ident, variants, tps)] + [filter_attrs(in_item), + enum_module(cx, in_item.ident, in_item.span, variants, tps)] } _ { @@ -118,9 +131,7 @@ impl helpers for ext_ctxt { fn next_id() -> ast::node_id { self.session().next_node_id() } fn path(span: span, strs: [str]) -> @ast::path { - @{node: {global: false, - idents: strs + ["serialize"], - types: []}, + @{node: {global: false, idents: strs, types: []}, span: span} } @@ -140,6 +151,28 @@ impl helpers for ser_cx { self.ext_cx.ty_path(span, strs) } + fn ty_fn(span: span, + -input_tys: [@ast::ty], + -output: @ast::ty) -> @ast::ty { + let args = vec::map(input_tys) {|ty| + {mode: ast::expl(ast::by_ref), + ty: ty, + ident: "", + id: self.next_id()} + }; + + @{node: ast::ty_fn(ast::proto_any, {inputs: args, + output: output, + purity: ast::impure_fn, + cf: ast::return_val, + constraints: []}), + span: span} + } + + fn ty_nil(span: span) -> @ast::ty { + @{node: ast::ty_nil, span: span} + } + fn expr(span: span, node: ast::expr_) -> @ast::expr { @{id: self.next_id(), node: node, span: span} } @@ -195,8 +228,9 @@ impl helpers for ser_cx { span: span})) } - fn lambda(-blk: @ast::blk) -> @ast::expr { - let blk_e = cx.expr(blk.span, expr_block(blk)); + fn lambda(blk: ast::blk) -> @ast::expr { + let ext_cx = self; + let blk_e = self.expr(blk.span, ast::expr_block(blk)); #ast(expr){{|| $(blk_e) }} } @@ -208,6 +242,14 @@ impl helpers for ser_cx { fld.fold_expr(v) } + fn clone_ty(v: @ast::ty) -> @ast::ty { + let fld = fold::make_fold({ + new_id: {|_id| self.next_id()} + with *fold::default_ast_fold() + }); + fld.fold_ty(v) + } + fn clone_ty_param(v: ast::ty_param) -> ast::ty_param { let fld = fold::make_fold({ new_id: {|_id| self.next_id()} @@ -249,14 +291,17 @@ fn serialize_path(cx: ser_cx, path: @ast::path, cx.path(path.span, path.node.idents + ["serialize"]))); let ty_args = vec::map(path.node.types) {|ty| - let sv = serialize_ty(cx, ty, s, #ast(expr){"__v"}); - cx.at(ty.span, #ast(expr){"{|__v| $(sv)}"}) + let sv_stmts = serialize_ty(cx, ty, cx.clone(s), #ast(expr){__v}); + let sv = cx.expr(path.span, + ast::expr_block(cx.blk(path.span, + sv_stmts))); + cx.at(ty.span, #ast(expr){{|__v| $(sv)}}) }; [cx.stmt( cx.expr( path.span, - ast::expr_call(callee, [s] + ty_args + [v], false)))] + ast::expr_call(callee, [s, v] + ty_args, false)))] } fn serialize_variant(cx: ser_cx, @@ -264,8 +309,8 @@ fn serialize_variant(cx: ser_cx, span: span, -s: @ast::expr, pfn: fn([@ast::pat]) -> ast::pat_, - bodyfn: fn(-@ast::expr, @ast::blk) -> @ast::expr, - argfn: fn(-@ast::expr, uint, @ast::blk) -> @ast::expr) + bodyfn: fn(-@ast::expr, ast::blk) -> @ast::expr, + argfn: fn(-@ast::expr, uint, ast::blk) -> @ast::expr) -> ast::arm { let vnames = vec::init_fn(vec::len(tys)) {|i| #fmt["__v%u", i]}; let pats = vec::init_fn(vec::len(tys)) {|i| @@ -281,7 +326,7 @@ fn serialize_variant(cx: ser_cx, cx.stmt(argfn(cx.clone(s), i, arg_blk)) }; - let body_blk = cx.blk(span, vec::concat(stmts)); + let body_blk = cx.blk(span, stmts); let body = cx.blk(span, [cx.stmt(bodyfn(s, body_blk))]); {pats: [pat], guard: none, body: body} @@ -289,6 +334,13 @@ fn serialize_variant(cx: ser_cx, fn serialize_ty(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr) -> [@ast::stmt] { + + fn ty_lambda(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr) + -> @ast::expr { + cx.lambda(cx.blk(ty.span, serialize_ty(cx, ty, s, v))) + } + + let ext_cx = cx.ext_cx; alt ty.node { @@ -296,19 +348,37 @@ fn serialize_ty(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr) [] } - ast::ty_box(mt) | - ast::ty_uniq(mt) | - ast::ty_ptr(mt) { - serialize_ty(cx, mt.ty, s, #ast(expr){"*$(v)"}) + ast::ty_box(mt) { + let l = ty_lambda(cx, mt.ty, cx.clone(s), #ast(expr){*$(v)}); + [#ast(stmt){$(s).emit_box($(l));}] + } + + ast::ty_uniq(mt) { + let l = ty_lambda(cx, mt.ty, cx.clone(s), #ast(expr){*$(v)}); + [#ast(stmt){$(s).emit_uniq($(l));}] + } + + ast::ty_ptr(_) | ast::ty_rptr(_, _) { + cx.session().span_err( + ty.span, #fmt["Cannot serialize pointer types"]); + [] } ast::ty_rec(flds) { - vec::flat_map(flds) {|fld| - let vf = cx.expr( - fld.span, - ast::expr_field(cx.clone(v), fld.node.ident, [])); - serialize_ty(cx, fld.node.mt.ty, cx.clone(s), vf) - } + let fld_stmts = vec::init_fn(vec::len(flds)) {|fidx| + let fld = flds[fidx]; + let vf = cx.expr(fld.span, + ast::expr_field(cx.clone(v), + fld.node.ident, + [])); + let s = cx.clone(s); + let f = cx.lit_str(fld.span, fld.node.ident); + let i = cx.lit_uint(fld.span, fidx); + let l = ty_lambda(cx, fld.node.mt.ty, cx.clone(s), vf); + #ast(stmt){$(s).emit_rec_field($(f), $(i), $(l));} + }; + let fld_lambda = cx.lambda(cx.blk(ty.span, fld_stmts)); + [#ast(stmt){$(s).emit_rec($(fld_lambda));}] } ast::ty_fn(_, _) { @@ -335,7 +405,7 @@ fn serialize_ty(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr) {|pats| ast::pat_tup(pats)}, // Generate body s.emit_tup(3, {|| blk }) - {|-s, -blk| + {|-s, blk| let sz = cx.lit_uint(ty.span, vec::len(tys)); let body = cx.lambda(blk); #ast[expr]{ @@ -344,7 +414,7 @@ fn serialize_ty(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr) }, // Generate s.emit_tup_elt(i, {|| blk }) - {|-s, i, -blk| + {|-s, i, blk| let idx = cx.lit_uint(ty.span, i); let body = cx.lambda(blk); #ast[expr]{ @@ -399,57 +469,55 @@ fn serialize_ty(cx: ser_cx, ty: @ast::ty, -s: @ast::expr, -v: @ast::expr) ty.span, #ast(expr){__e}))))); - [cx.stmt( - cx.expr( - ty.span, - ast::expr_call( - #ast(expr){$(s).emit_from_vec}, - [#ast(expr){{|__e| $(ser_e)}}], - false)))] + [#ast(stmt){ + core::serialization::emit_from_vec($(s), $(v), {|__e| $(ser_e) }) + }] } } } fn mk_ser_fn(ext_cx: ext_ctxt, span: span, - -v_ty: @ast::ty, tps: [ast::ty_param], + v_ty: @ast::ty, tps: [ast::ty_param], f: fn(ser_cx, @ast::ty, -@ast::expr, -@ast::expr) -> [@ast::stmt]) -> @ast::item { - let cx = ser_cx({ext_cx: ext_cx, tps: map::new_str_hash()}); + let cx = ser_cx(@{ext_cx: ext_cx, tps: map::new_str_hash()}); let tp_inputs = vec::map(tps, {|tp| {mode: ast::expl(ast::by_ref), - ty: cx.ty_path(span, [tp.ident]), + ty: cx.ty_fn(span, + [cx.ty_path(span, [tp.ident])], + cx.ty_nil(span)), ident: "__s" + tp.ident, id: cx.next_id()}}); + #debug["tp_inputs = %?", tp_inputs]; + let ser_inputs: [ast::arg] = [{mode: ast::expl(ast::by_ref), ty: cx.ty_path(span, ["__S"]), ident: "__s", id: cx.next_id()}, {mode: ast::expl(ast::by_ref), - ty: v_ty, + ty: cx.clone_ty(v_ty), ident: "__v", id: cx.next_id()}] + tp_inputs; - vec::iter2(tps, ser_inputs) {|tp, arg| + vec::iter2(tps, tp_inputs) {|tp, arg| let arg_ident = arg.ident; cx.tps.insert( tp.ident, fn@(v: @ast::expr) -> [@ast::stmt] { let f = cx.var_ref(span, arg_ident); - [cx.stmt( - cx.expr( - span, - ast::expr_call(f, [v], false)))] + #debug["serializing type arg %s", arg_ident]; + [#ast(stmt){$(f)($(v));}] }); } let ser_bnds = @[ast::bound_iface(cx.ty_path(span, - ["__std", "serialization", + ["serialization", "serializer"]))]; let ser_tps: [ast::ty_param] = @@ -462,7 +530,7 @@ fn mk_ser_fn(ext_cx: ext_ctxt, span: span, span: span}; let ser_blk = cx.blk(span, - f(cx, v_ty, #ast(expr){"__s"}, #ast(expr){"__v"})); + f(cx, v_ty, #ast(expr){__s}, #ast(expr){__v})); @{ident: "serialize", attrs: [], @@ -477,7 +545,7 @@ fn mk_ser_fn(ext_cx: ext_ctxt, span: span, span: span} } -fn ty_module(ext_cx: ext_ctxt, name: str, -ty: @ast::ty, tps: [ast::ty_param]) +fn ty_module(ext_cx: ext_ctxt, name: str, ty: @ast::ty, tps: [ast::ty_param]) -> @ast::item { let span = ty.span; @@ -497,62 +565,51 @@ fn enum_module(ext_cx: ext_ctxt, name: str, span: span, variants: [ast::variant], tps: [ast::ty_param]) -> @ast::item { - let span = ty.span; let ty = ext_cx.ty_path(span, [name]); - let ser_fn = mk_ser_fn(ext_cx, span, ty, tps) {|cx, ty, s, v| - let arms = vec::init_fn(vec::len(variants)) {|vidx| - let variant = variants[vidx]; - - if vec::is_empty(variant.args) { - // degenerate case. - let pat = {id: cx.next_id(), - node: ast::pat_ident(cx.path(variant.ident), none), - Span: variant.span}; - //#ast(expr){ - // $(s).emit_enum_variant(X, Y, SZ) {|| - // }; - //} - } - - let variant_tys = vec::map(variant.args) {|a| a.ty }; - - serialize_variant( - cx, variant_tys, variant.span, cx.clone(s), - - // Generate pattern var(v1, v2, v3) - {|pats| - let pat = {id: cx.next_id(), - node: ast::pat_enum(cx.path(variant.ident)), - span: variant.span}; - - {id: cx.next_id(), - node: expr_call(s, [v_name, - v_id, - sz, - f], false), - span: variant.span} - }, - - // Generate body s.emit_enum_variant("foo", 0u, 3u, {|| blk }) - {|-s, -blk| - let v_name = cx.lit_str(variant.span, variant.ident); - let v_id = cx.lit_uint(variant.span, vidx); - let sz = cx.lit_uint(variant.span, vec::len(variant_tys)); - let body = cx.lambda(blk); - #ast[expr]{ - $(s).emit_enum_variant($(v_name), $(v_id), $(sz), $(body)) - } - }, - - // Generate s.emit_enum_variant_arg(i, {|| blk }) - {|-s, i, -blk| - let idx = cx.lit_uint(i); - let body = cx.lambda(blk); - #ast[expr]{ - $(s).emit_enum_variant_arg($(idx), $(body)) - } - }) - }; + let ser_fn = mk_ser_fn(ext_cx, span, ty, tps) {|cx, _ty, s, v| + let arms = vec::init_fn( + vec::len(variants), + fn&(vidx: uint) -> ast::arm { + let variant = variants[vidx]; + let span = variant.span; + let name = variant.node.name; + let variant_tys = vec::map(variant.node.args) {|a| a.ty }; + + serialize_variant( + cx, variant_tys, span, cx.clone(s), + + // Generate pattern var(v1, v2, v3) + {|pats| + if vec::is_empty(pats) { + ast::pat_ident(cx.path(span, [name]), none) + } else { + ast::pat_enum(cx.path(span, [name]), pats) + } + }, + + // Generate body s.emit_enum_variant("foo", 0u, + // 3u, {|| blk }) + {|-s, blk| + let v_name = cx.lit_str(span, name); + let v_id = cx.lit_uint(span, vidx); + let sz = cx.lit_uint(span, vec::len(variant_tys)); + let body = cx.lambda(blk); + #ast[expr]{ + $(s).emit_enum_variant($(v_name), $(v_id), + $(sz), $(body)) + } + }, + + // Generate s.emit_enum_variant_arg(i, {|| blk }) + {|-s, i, blk| + let idx = cx.lit_uint(span, i); + let body = cx.lambda(blk); + #ast[expr]{ + $(s).emit_enum_variant_arg($(idx), $(body)) + } + }) + }); + [cx.alt_stmt(arms, span, v)] }; @{ident: name, diff --git a/src/rustc/syntax/ext/base.rs b/src/rustc/syntax/ext/base.rs index 721f059ee35..014cc17b5d5 100644 --- a/src/rustc/syntax/ext/base.rs +++ b/src/rustc/syntax/ext/base.rs @@ -27,6 +27,8 @@ fn syntax_expander_table() -> hashmap { {normal({expander: f, span: none})} let syntax_expanders = new_str_hash::(); syntax_expanders.insert("fmt", builtin(ext::fmt::expand_syntax_ext)); + syntax_expanders.insert("auto_serialize", + item_decorator(ext::auto_serialize::expand)); syntax_expanders.insert("env", builtin(ext::env::expand_syntax_ext)); syntax_expanders.insert("macro", macro_defining(ext::simplext::add_new_extension)); diff --git a/src/rustc/syntax/ext/qquote.rs b/src/rustc/syntax/ext/qquote.rs index f93a4019c31..742e7ce45d9 100644 --- a/src/rustc/syntax/ext/qquote.rs +++ b/src/rustc/syntax/ext/qquote.rs @@ -193,6 +193,7 @@ fn finish { let cm = ecx.session().parse_sess.cm; let str = @codemap::span_to_snippet(body.span, cm); + #debug["qquote--str==%?", str]; let fname = codemap::mk_substr_filename(cm, body.span); let node = parse_from_source_str (f, fname, codemap::fss_internal(body.span), str, -- cgit 1.4.1-3-g733a5