about summary refs log tree commit diff
path: root/src/comp/syntax
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-10-06 12:26:12 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-10-07 09:09:50 +0200
commitf9fbd86f52cf597b85359ade1ca60b8d6ebf7286 (patch)
treed6f0cdd039642052f3ccb4ba8f3b9821bb7cbaaf /src/comp/syntax
parent4709038d641ad009b44ed2bf5980fa3a252d6927 (diff)
downloadrust-f9fbd86f52cf597b85359ade1ca60b8d6ebf7286.tar.gz
rust-f9fbd86f52cf597b85359ade1ca60b8d6ebf7286.zip
Parse and typecheck by-value and by-ref arg specs
Add sprinkle && throughout the compiler to make it typecheck again.

Issue #1008
Diffstat (limited to 'src/comp/syntax')
-rw-r--r--src/comp/syntax/ast.rs2
-rw-r--r--src/comp/syntax/ast_util.rs4
-rw-r--r--src/comp/syntax/ext/simplext.rs4
-rw-r--r--src/comp/syntax/fold.rs62
-rw-r--r--src/comp/syntax/parse/parser.rs19
-rw-r--r--src/comp/syntax/print/pprust.rs30
-rw-r--r--src/comp/syntax/visit.rs28
7 files changed, 73 insertions, 76 deletions
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index 52aa6cb31d9..1864af6de9e 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -132,7 +132,7 @@ tag unop {
     deref; not; neg;
 }
 
-tag mode { by_ref; by_mut_ref; by_move; }
+tag mode { by_ref; by_val; by_mut_ref; by_move; mode_infer; }
 
 type stmt = spanned<stmt_>;
 
diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs
index c4d0272b95f..d70b63dac67 100644
--- a/src/comp/syntax/ast_util.rs
+++ b/src/comp/syntax/ast_util.rs
@@ -180,9 +180,9 @@ fn is_constraint_arg(e: @expr) -> bool {
     }
 }
 
-fn eq_ty(a: @ty, b: @ty) -> bool { ret std::box::ptr_eq(a, b); }
+fn eq_ty(&&a: @ty, &&b: @ty) -> bool { ret std::box::ptr_eq(a, b); }
 
-fn hash_ty(t: @ty) -> uint { ret t.span.lo << 16u + t.span.hi; }
+fn hash_ty(&&t: @ty) -> uint { ret t.span.lo << 16u + t.span.hi; }
 
 fn block_from_expr(e: @expr) -> blk {
     let blk_ = checked_blk([], option::some::<@expr>(e), e.id);
diff --git a/src/comp/syntax/ext/simplext.rs b/src/comp/syntax/ext/simplext.rs
index 528b2cdc756..5fafcdbb437 100644
--- a/src/comp/syntax/ext/simplext.rs
+++ b/src/comp/syntax/ext/simplext.rs
@@ -266,7 +266,7 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
                     recur: fn(@expr) -> @expr, exprs: [@expr]) -> [@expr] {
     alt elts_to_ell(cx, exprs) {
       {pre: pre, rep: repeat_me_maybe, post: post} {
-        let res = vec::map(recur, pre);
+        let res = vec::map_imm(recur, pre);
         alt repeat_me_maybe {
           none. { }
           some(repeat_me) {
@@ -315,7 +315,7 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
             }
           }
         }
-        res += vec::map(recur, post);
+        res += vec::map_imm(recur, post);
         ret res;
       }
     }
diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs
index bf8504f3c1a..edee54fb808 100644
--- a/src/comp/syntax/fold.rs
+++ b/src/comp/syntax/fold.rs
@@ -110,7 +110,7 @@ fn fold_meta_item_(mi: @meta_item, fld: ast_fold) -> @meta_item {
                 meta_word(id) { meta_word(fld.fold_ident(id)) }
                 meta_list(id, mis) {
                   let fold_meta_item = bind fold_meta_item_(_, fld);
-                  meta_list(id, vec::map(fold_meta_item, mis))
+                  meta_list(id, vec::map_imm(fold_meta_item, mis))
                 }
                 meta_name_value(id, s) {
                   meta_name_value(fld.fold_ident(id), s)
@@ -153,10 +153,10 @@ fn noop_fold_crate(c: crate_, fld: ast_fold) -> crate_ {
     let fold_meta_item = bind fold_meta_item_(_, fld);
     let fold_attribute = bind fold_attribute_(_, fold_meta_item);
 
-    ret {directives: vec::map(fld.fold_crate_directive, c.directives),
+    ret {directives: vec::map_imm(fld.fold_crate_directive, c.directives),
          module: fld.fold_mod(c.module),
          attrs: vec::map(fold_attribute, c.attrs),
-         config: vec::map(fold_meta_item, c.config)};
+         config: vec::map_imm(fold_meta_item, c.config)};
 }
 
 fn noop_fold_crate_directive(cd: crate_directive_, fld: ast_fold) ->
@@ -167,7 +167,7 @@ fn noop_fold_crate_directive(cd: crate_directive_, fld: ast_fold) ->
           }
           cdir_dir_mod(id, fname, cds, attrs) {
             cdir_dir_mod(fld.fold_ident(id), fname,
-                         vec::map(fld.fold_crate_directive, cds), attrs)
+                         vec::map_imm(fld.fold_crate_directive, cds), attrs)
           }
           cdir_view_item(vi) { cdir_view_item(fld.fold_view_item(vi)) }
           cdir_syntax(_) { cd }
@@ -198,8 +198,8 @@ fn noop_fold_native_item(ni: @native_item, fld: ast_fold) -> @native_item {
                                   il: fdec.il,
                                   cf: fdec.cf,
                                   constraints:
-                                      vec::map(fld.fold_constr,
-                                               fdec.constraints)}, typms)
+                                      vec::map_imm(fld.fold_constr,
+                                                   fdec.constraints)}, typms)
                 }
               },
           id: ni.id,
@@ -237,8 +237,8 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
           }
           item_obj(o, typms, d) {
             item_obj({fields: vec::map(fold_obj_field, o.fields),
-                      methods: vec::map(fld.fold_method, o.methods)}, typms,
-                     d)
+                      methods: vec::map_imm(fld.fold_method, o.methods)},
+                     typms, d)
           }
           item_res(dtor, did, typms, cid) {
             item_res(fld.fold_fn(dtor), did, typms, cid)
@@ -252,8 +252,8 @@ fn noop_fold_method(m: method_, fld: ast_fold) -> method_ {
 
 
 fn noop_fold_block(b: blk_, fld: ast_fold) -> blk_ {
-    ret {stmts: vec::map(fld.fold_stmt, b.stmts),
-         expr: option::map(fld.fold_expr, b.expr),
+    ret {stmts: vec::map_imm(fld.fold_stmt, b.stmts),
+         expr: option::map_imm(fld.fold_expr, b.expr),
          id: b.id,
          rules: b.rules};
 }
@@ -269,8 +269,8 @@ fn noop_fold_stmt(s: stmt_, fld: ast_fold) -> stmt_ {
 }
 
 fn noop_fold_arm(a: arm, fld: ast_fold) -> arm {
-    ret {pats: vec::map(fld.fold_pat, a.pats),
-         guard: option::map(fld.fold_expr, a.guard),
+    ret {pats: vec::map_imm(fld.fold_pat, a.pats),
+         guard: option::map_imm(fld.fold_expr, a.guard),
          body: fld.fold_block(a.body)};
 }
 
@@ -280,7 +280,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
           pat_bind(ident) { pat_bind(fld.fold_ident(ident)) }
           pat_lit(_) { p }
           pat_tag(pth, pats) {
-            pat_tag(fld.fold_path(pth), vec::map(fld.fold_pat, pats))
+            pat_tag(fld.fold_path(pth), vec::map_imm(fld.fold_pat, pats))
           }
           pat_rec(fields, etc) {
             let fs = [];
@@ -289,7 +289,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
             }
             pat_rec(fs, etc)
           }
-          pat_tup(elts) { pat_tup(vec::map(fld.fold_pat, elts)) }
+          pat_tup(elts) { pat_tup(vec::map_imm(fld.fold_pat, elts)) }
           pat_box(inner) { pat_box(fld.fold_pat(inner)) }
           pat_uniq(inner) { pat_uniq(fld.fold_pat(inner)) }
           pat_range(_, _) { p }
@@ -334,8 +334,8 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
                      option::some(vec::map(fold_anon_obj_field, v))
                    }
                  },
-             methods: vec::map(fld.fold_method, ao.methods),
-             inner_obj: option::map(fld.fold_expr, ao.inner_obj)}
+             methods: vec::map_imm(fld.fold_method, ao.methods),
+             inner_obj: option::map_imm(fld.fold_expr, ao.inner_obj)}
     }
     let fold_anon_obj = bind fold_anon_obj_(_, fld);
 
@@ -347,15 +347,15 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
           }
           expr_rec(fields, maybe_expr) {
             expr_rec(vec::map(fold_field, fields),
-                     option::map(fld.fold_expr, maybe_expr))
+                     option::map_imm(fld.fold_expr, maybe_expr))
           }
-          expr_tup(elts) { expr_tup(vec::map(fld.fold_expr, elts)) }
+          expr_tup(elts) { expr_tup(vec::map_imm(fld.fold_expr, elts)) }
           expr_call(f, args) {
             expr_call(fld.fold_expr(f), fld.map_exprs(fld.fold_expr, args))
           }
           expr_self_method(id) { expr_self_method(fld.fold_ident(id)) }
           expr_bind(f, args) {
-            let opt_map_se = bind option::map(fld.fold_expr, _);
+            let opt_map_se = bind option::map_imm(fld.fold_expr, _);
             expr_bind(fld.fold_expr(f), vec::map(opt_map_se, args))
           }
           expr_binary(binop, lhs, rhs) {
@@ -366,7 +366,7 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
           expr_cast(expr, ty) { expr_cast(fld.fold_expr(expr), ty) }
           expr_if(cond, tr, fl) {
             expr_if(fld.fold_expr(cond), fld.fold_block(tr),
-                    option::map(fld.fold_expr, fl))
+                    option::map_imm(fld.fold_expr, fl))
           }
           expr_ternary(cond, tr, fl) {
             expr_ternary(fld.fold_expr(cond), fld.fold_expr(tr),
@@ -411,18 +411,18 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
             expr_index(fld.fold_expr(el), fld.fold_expr(er))
           }
           expr_path(pth) { expr_path(fld.fold_path(pth)) }
-          expr_fail(e) { expr_fail(option::map(fld.fold_expr, e)) }
+          expr_fail(e) { expr_fail(option::map_imm(fld.fold_expr, e)) }
           expr_break. { e }
           expr_cont. { e }
-          expr_ret(e) { expr_ret(option::map(fld.fold_expr, e)) }
-          expr_put(e) { expr_put(option::map(fld.fold_expr, e)) }
+          expr_ret(e) { expr_ret(option::map_imm(fld.fold_expr, e)) }
+          expr_put(e) { expr_put(option::map_imm(fld.fold_expr, e)) }
           expr_be(e) { expr_be(fld.fold_expr(e)) }
           expr_log(lv, e) { expr_log(lv, fld.fold_expr(e)) }
           expr_assert(e) { expr_assert(fld.fold_expr(e)) }
           expr_check(m, e) { expr_check(m, fld.fold_expr(e)) }
           expr_if_check(cond, tr, fl) {
             expr_if_check(fld.fold_expr(cond), fld.fold_block(tr),
-                          option::map(fld.fold_expr, fl))
+                          option::map_imm(fld.fold_expr, fl))
           }
           expr_anon_obj(ao) { expr_anon_obj(fold_anon_obj(ao)) }
           expr_mac(mac) { expr_mac(fold_mac(mac)) }
@@ -448,22 +448,22 @@ fn noop_fold_fn(f: _fn, fld: ast_fold) -> _fn {
               purity: f.decl.purity,
               il: f.decl.il,
               cf: f.decl.cf,
-              constraints: vec::map(fld.fold_constr, f.decl.constraints)},
+              constraints: vec::map_imm(fld.fold_constr, f.decl.constraints)},
          proto: f.proto,
          body: fld.fold_block(f.body)};
 }
 
 // ...nor do modules
 fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod {
-    ret {view_items: vec::map(fld.fold_view_item, m.view_items),
-         items: vec::map(fld.fold_item, m.items)};
+    ret {view_items: vec::map_imm(fld.fold_view_item, m.view_items),
+         items: vec::map_imm(fld.fold_item, m.items)};
 }
 
 fn noop_fold_native_mod(nm: native_mod, fld: ast_fold) -> native_mod {
     ret {native_name: nm.native_name,
          abi: nm.abi,
-         view_items: vec::map(fld.fold_view_item, nm.view_items),
-         items: vec::map(fld.fold_native_item, nm.items)}
+         view_items: vec::map_imm(fld.fold_view_item, nm.view_items),
+         items: vec::map_imm(fld.fold_native_item, nm.items)}
 }
 
 fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
@@ -479,7 +479,7 @@ fn noop_fold_ident(i: ident, _fld: ast_fold) -> ident { ret i; }
 fn noop_fold_path(p: path_, fld: ast_fold) -> path_ {
     ret {global: p.global,
          idents: vec::map(fld.fold_ident, p.idents),
-         types: vec::map(fld.fold_ty, p.types)};
+         types: vec::map_imm(fld.fold_ty, p.types)};
 }
 
 fn noop_fold_local(l: local_, fld: ast_fold) -> local_ {
@@ -499,7 +499,7 @@ fn noop_fold_local(l: local_, fld: ast_fold) -> local_ {
 /* temporarily eta-expand because of a compiler bug with using `fn<T>` as a
    value */
 fn noop_map_exprs(f: fn(@expr) -> @expr, es: [@expr]) -> [@expr] {
-    ret vec::map(f, es);
+    ret vec::map_imm(f, es);
 }
 
 fn noop_id(i: node_id) -> node_id { ret i; }
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 53c3aa01bf0..e220149f6f8 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -587,17 +587,11 @@ fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
 }
 
 fn parse_arg_mode(p: parser) -> ast::mode {
-    if eat(p, token::BINOP(token::AND)) {
-        ret ast::by_mut_ref;
-    } else if eat(p, token::BINOP(token::MINUS)) {
-        ret ast::by_move;
-    } else {
-        // FIXME Temporarily ignore these, to make it possible to implement
-        // them without breaking the stage0 build.
-        eat(p, token::ANDAND);
-        eat(p, token::BINOP(token::PLUS));
-        ret ast::by_ref;
-    }
+    if eat(p, token::BINOP(token::AND)) { ast::by_mut_ref }
+    else if eat(p, token::BINOP(token::MINUS)) { ast::by_move }
+    else if eat(p, token::ANDAND) { ast::by_ref }
+    else if eat(p, token::BINOP(token::PLUS)) { ast::by_val }
+    else { ast::mode_infer }
 }
 
 fn parse_arg(p: parser) -> ast::arg {
@@ -1890,7 +1884,8 @@ fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item {
     let dtor = parse_block_no_value(p);
     let decl =
         {inputs:
-             [{mode: ast::by_ref, ty: t, ident: arg_ident, id: p.get_id()}],
+             [{mode: ast::by_ref, ty: t, ident: arg_ident,
+               id: p.get_id()}],
          output: @spanned(lo, lo, ast::ty_nil),
          purity: ast::impure_fn,
          il: ast::il_normal,
diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs
index 555cd7fddee..a24b4c9b984 100644
--- a/src/comp/syntax/print/pprust.rs
+++ b/src/comp/syntax/print/pprust.rs
@@ -226,7 +226,7 @@ fn commasep_cmnt<IN>(s: ps, b: breaks, elts: [IN], op: fn(ps, IN),
 }
 
 fn commasep_exprs(s: ps, b: breaks, exprs: [@ast::expr]) {
-    fn expr_span(expr: @ast::expr) -> codemap::span { ret expr.span; }
+    fn expr_span(&&expr: @ast::expr) -> codemap::span { ret expr.span; }
     commasep_cmnt(s, b, exprs, print_expr, expr_span);
 }
 
@@ -246,7 +246,7 @@ fn print_native_mod(s: ps, nmod: ast::native_mod, attrs: [ast::attribute]) {
     for item: @ast::native_item in nmod.items { print_native_item(s, item); }
 }
 
-fn print_type(s: ps, ty: @ast::ty) {
+fn print_type(s: ps, &&ty: @ast::ty) {
     maybe_print_comment(s, ty.span.lo);
     ibox(s, 0u);
     alt ty.node {
@@ -365,7 +365,7 @@ fn print_native_item(s: ps, item: @ast::native_item) {
     }
 }
 
-fn print_item(s: ps, item: @ast::item) {
+fn print_item(s: ps, &&item: @ast::item) {
     hardbreak_if_not_bol(s);
     maybe_print_comment(s, item.span.lo);
     print_outer_attributes(s, item.attrs);
@@ -678,7 +678,7 @@ fn print_mac(s: ps, m: ast::mac) {
     }
 }
 
-fn print_expr(s: ps, expr: @ast::expr) {
+fn print_expr(s: ps, &&expr: @ast::expr) {
     maybe_print_comment(s, expr.span.lo);
     ibox(s, indent_unit);
     let ann_node = node_expr(s, expr);
@@ -1080,7 +1080,7 @@ fn print_path(s: ps, path: ast::path, colons_before_params: bool) {
     }
 }
 
-fn print_pat(s: ps, pat: @ast::pat) {
+fn print_pat(s: ps, &&pat: @ast::pat) {
     maybe_print_comment(s, pat.span.lo);
     let ann_node = node_pat(s, pat);
     s.ann.pre(ann_node);
@@ -1145,7 +1145,7 @@ fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl, constrs: [@ast::constr]) {
     popen(s);
     fn print_arg(s: ps, x: ast::arg) {
         ibox(s, indent_unit);
-        print_alias(s, x.mode);
+        print_arg_mode(s, x.mode);
         word_space(s, x.ident + ":");
         print_type(s, x.ty);
         end(s);
@@ -1174,7 +1174,7 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl) {
     word(s.s, "|");
     fn print_arg(s: ps, x: ast::arg) {
         ibox(s, indent_unit);
-        print_alias(s, x.mode);
+        print_arg_mode(s, x.mode);
         word(s.s, x.ident);
         end(s);
     }
@@ -1183,11 +1183,13 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl) {
     maybe_print_comment(s, decl.output.span.lo);
 }
 
-fn print_alias(s: ps, m: ast::mode) {
+fn print_arg_mode(s: ps, m: ast::mode) {
     alt m {
       ast::by_mut_ref. { word(s.s, "&"); }
       ast::by_move. { word(s.s, "-"); }
-      ast::by_ref. { }
+      ast::by_ref. { word(s.s, "&&"); }
+      ast::by_val. { word(s.s, "+"); }
+      ast::mode_infer. {}
     }
 }
 
@@ -1211,7 +1213,7 @@ fn print_type_params(s: ps, params: [ast::ty_param]) {
     }
 }
 
-fn print_meta_item(s: ps, item: @ast::meta_item) {
+fn print_meta_item(s: ps, &&item: @ast::meta_item) {
     ibox(s, indent_unit);
     alt item.node {
       ast::meta_word(name) { word(s.s, name); }
@@ -1351,7 +1353,7 @@ fn print_ty_fn(s: ps, proto: ast::proto, id: option::t<ast::ident>,
     zerobreak(s.s);
     popen(s);
     fn print_arg(s: ps, input: ast::ty_arg) {
-        print_alias(s, input.node.mode);
+        print_arg_mode(s, input.node.mode);
         print_type(s, input.node.ty);
     }
     commasep(s, inconsistent, inputs, print_arg);
@@ -1418,7 +1420,7 @@ fn in_cbox(s: ps) -> bool {
     ret s.boxes[len - 1u] == pp::consistent;
 }
 
-fn print_literal(s: ps, lit: @ast::lit) {
+fn print_literal(s: ps, &&lit: @ast::lit) {
     maybe_print_comment(s, lit.span.lo);
     alt next_lit(s) {
       some(lt) {
@@ -1596,7 +1598,7 @@ fn constr_arg_to_str<T>(f: fn(T) -> str, c: ast::constr_arg_general_<T>) ->
 // needed b/c constr_args_to_str needs
 // something that takes an alias
 // (argh)
-fn uint_to_str(i: uint) -> str { ret uint::str(i); }
+fn uint_to_str(&&i: uint) -> str { ret uint::str(i); }
 
 fn ast_ty_fn_constr_to_str(c: @ast::constr) -> str {
     ret path_to_str(c.node.path) +
@@ -1614,7 +1616,7 @@ fn ast_ty_fn_constrs_str(constrs: [@ast::constr]) -> str {
     ret s;
 }
 
-fn fn_arg_idx_to_str(decl: ast::fn_decl, idx: uint) -> str {
+fn fn_arg_idx_to_str(decl: ast::fn_decl, &&idx: uint) -> str {
     decl.inputs[idx].ident
 }
 
diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs
index 2a002c3ada3..f234c2fb221 100644
--- a/src/comp/syntax/visit.rs
+++ b/src/comp/syntax/visit.rs
@@ -377,62 +377,62 @@ fn default_simple_visitor() -> simple_visitor {
 }
 
 fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
-    fn v_mod(f: fn(_mod, span), m: _mod, sp: span, e: (), v: vt<()>) {
+    fn v_mod(f: fn(_mod, span), m: _mod, sp: span, &&e: (), v: vt<()>) {
         f(m, sp);
         visit_mod(m, sp, e, v);
     }
-    fn v_view_item(f: fn(@view_item), vi: @view_item, e: (), v: vt<()>) {
+    fn v_view_item(f: fn(@view_item), vi: @view_item, &&e: (), v: vt<()>) {
         f(vi);
         visit_view_item(vi, e, v);
     }
-    fn v_native_item(f: fn(@native_item), ni: @native_item, e: (),
+    fn v_native_item(f: fn(@native_item), ni: @native_item, &&e: (),
                      v: vt<()>) {
         f(ni);
         visit_native_item(ni, e, v);
     }
-    fn v_item(f: fn(@item), i: @item, e: (), v: vt<()>) {
+    fn v_item(f: fn(@item), i: @item, &&e: (), v: vt<()>) {
         f(i);
         visit_item(i, e, v);
     }
-    fn v_local(f: fn(@local), l: @local, e: (), v: vt<()>) {
+    fn v_local(f: fn(@local), l: @local, &&e: (), v: vt<()>) {
         f(l);
         visit_local(l, e, v);
     }
-    fn v_block(f: fn(ast::blk), bl: ast::blk, e: (), v: vt<()>) {
+    fn v_block(f: fn(ast::blk), bl: ast::blk, &&e: (), v: vt<()>) {
         f(bl);
         visit_block(bl, e, v);
     }
-    fn v_stmt(f: fn(@stmt), st: @stmt, e: (), v: vt<()>) {
+    fn v_stmt(f: fn(@stmt), st: @stmt, &&e: (), v: vt<()>) {
         f(st);
         visit_stmt(st, e, v);
     }
-    fn v_arm(f: fn(arm), a: arm, e: (), v: vt<()>) {
+    fn v_arm(f: fn(arm), a: arm, &&e: (), v: vt<()>) {
         f(a);
         visit_arm(a, e, v);
     }
-    fn v_pat(f: fn(@pat), p: @pat, e: (), v: vt<()>) {
+    fn v_pat(f: fn(@pat), p: @pat, &&e: (), v: vt<()>) {
         f(p);
         visit_pat(p, e, v);
     }
-    fn v_decl(f: fn(@decl), d: @decl, e: (), v: vt<()>) {
+    fn v_decl(f: fn(@decl), d: @decl, &&e: (), v: vt<()>) {
         f(d);
         visit_decl(d, e, v);
     }
-    fn v_expr(f: fn(@expr), ex: @expr, e: (), v: vt<()>) {
+    fn v_expr(f: fn(@expr), ex: @expr, &&e: (), v: vt<()>) {
         f(ex);
         visit_expr(ex, e, v);
     }
-    fn v_ty(f: fn(@ty), ty: @ty, e: (), v: vt<()>) {
+    fn v_ty(f: fn(@ty), ty: @ty, &&e: (), v: vt<()>) {
         f(ty);
         visit_ty(ty, e, v);
     }
     fn v_constr(f: fn(path, span, node_id), pt: path, sp: span, id: node_id,
-                e: (), v: vt<()>) {
+                &&e: (), v: vt<()>) {
         f(pt, sp, id);
         visit_constr(pt, sp, id, e, v);
     }
     fn v_fn(f: fn(_fn, [ty_param], span, fn_ident, node_id), ff: _fn,
-            tps: [ty_param], sp: span, ident: fn_ident, id: node_id, e: (),
+            tps: [ty_param], sp: span, ident: fn_ident, id: node_id, &&e: (),
             v: vt<()>) {
         f(ff, tps, sp, ident, id);
         visit_fn(ff, tps, sp, ident, id, e, v);