about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-06-15 20:26:59 -0400
committerNiko Matsakis <niko@alum.mit.edu>2013-06-16 12:47:36 -0400
commiteb48c296817be7529a1757ac8d4798112717eaa9 (patch)
treed90d4c97be651ac615f86c6ff74b682218ee1e1c /src/libsyntax
parent682bb4144ca3fddffee8ed2927e7552049fcf25c (diff)
downloadrust-eb48c296817be7529a1757ac8d4798112717eaa9.tar.gz
rust-eb48c296817be7529a1757ac8d4798112717eaa9.zip
Add copies to type params with Copy bound
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast_util.rs52
-rw-r--r--src/libsyntax/diagnostic.rs2
-rw-r--r--src/libsyntax/print/pprust.rs12
-rw-r--r--src/libsyntax/util/interner.rs6
-rw-r--r--src/libsyntax/visit.rs212
5 files changed, 149 insertions, 135 deletions
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index cc89db6e189..07913946578 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -395,30 +395,30 @@ impl id_range {
 pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
     let visit_generics: @fn(&Generics, T) = |generics, t| {
         for generics.ty_params.each |p| {
-            vfn(p.id, t);
+            vfn(p.id, copy t);
         }
         for generics.lifetimes.each |p| {
-            vfn(p.id, t);
+            vfn(p.id, copy t);
         }
     };
     visit::mk_vt(@visit::Visitor {
         visit_mod: |m, sp, id, (t, vt)| {
-            vfn(id, t);
+            vfn(id, copy t);
             visit::visit_mod(m, sp, id, (t, vt));
         },
 
         visit_view_item: |vi, (t, vt)| {
             match vi.node {
-              view_item_extern_mod(_, _, id) => vfn(id, t),
+              view_item_extern_mod(_, _, id) => vfn(id, copy t),
               view_item_use(ref vps) => {
                   for vps.each |vp| {
                       match vp.node {
-                          view_path_simple(_, _, id) => vfn(id, t),
-                          view_path_glob(_, id) => vfn(id, t),
+                          view_path_simple(_, _, id) => vfn(id, copy t),
+                          view_path_glob(_, id) => vfn(id, copy t),
                           view_path_list(_, ref paths, id) => {
-                              vfn(id, t);
+                              vfn(id, copy t);
                               for paths.each |p| {
-                                  vfn(p.node.id, t);
+                                  vfn(p.node.id, copy t);
                               }
                           }
                       }
@@ -429,34 +429,34 @@ pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
         },
 
         visit_foreign_item: |ni, (t, vt)| {
-            vfn(ni.id, t);
+            vfn(ni.id, copy t);
             visit::visit_foreign_item(ni, (t, vt));
         },
 
         visit_item: |i, (t, vt)| {
-            vfn(i.id, t);
+            vfn(i.id, copy t);
             match i.node {
               item_enum(ref enum_definition, _) =>
-                for (*enum_definition).variants.each |v| { vfn(v.node.id, t); },
+                for (*enum_definition).variants.each |v| { vfn(v.node.id, copy t); },
               _ => ()
             }
             visit::visit_item(i, (t, vt));
         },
 
         visit_local: |l, (t, vt)| {
-            vfn(l.node.id, t);
+            vfn(l.node.id, copy t);
             visit::visit_local(l, (t, vt));
         },
         visit_block: |b, (t, vt)| {
-            vfn(b.node.id, t);
+            vfn(b.node.id, copy t);
             visit::visit_block(b, (t, vt));
         },
         visit_stmt: |s, (t, vt)| {
-            vfn(ast_util::stmt_id(s), t);
+            vfn(ast_util::stmt_id(s), copy t);
             visit::visit_stmt(s, (t, vt));
         },
         visit_pat: |p, (t, vt)| {
-            vfn(p.id, t);
+            vfn(p.id, copy t);
             visit::visit_pat(p, (t, vt));
         },
 
@@ -464,36 +464,36 @@ pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
             {
                 let r = e.get_callee_id();
                 for r.iter().advance |callee_id| {
-                    vfn(*callee_id, t);
+                    vfn(*callee_id, copy t);
                 }
             }
-            vfn(e.id, t);
+            vfn(e.id, copy t);
             visit::visit_expr(e, (t, vt));
         },
 
         visit_ty: |ty, (t, vt)| {
             match ty.node {
-              ty_path(_, id) => vfn(id, t),
+              ty_path(_, id) => vfn(id, copy t),
               _ => { /* fall through */ }
             }
             visit::visit_ty(ty, (t, vt));
         },
 
         visit_generics: |generics, (t, vt)| {
-            visit_generics(generics, t);
+            visit_generics(generics, copy t);
             visit::visit_generics(generics, (t, vt));
         },
 
         visit_fn: |fk, d, a, b, id, (t, vt)| {
-            vfn(id, t);
+            vfn(id, copy t);
 
             match *fk {
                 visit::fk_item_fn(_, generics, _, _) => {
-                    visit_generics(generics, t);
+                    visit_generics(generics, copy t);
                 }
                 visit::fk_method(_, generics, m) => {
-                    vfn(m.self_id, t);
-                    visit_generics(generics, t);
+                    vfn(m.self_id, copy t);
+                    visit_generics(generics, copy t);
                 }
                 visit::fk_anon(_) |
                 visit::fk_fn_block => {
@@ -501,13 +501,13 @@ pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
             }
 
             for d.inputs.each |arg| {
-                vfn(arg.id, t)
+                vfn(arg.id, copy t)
             }
-            visit::visit_fn(fk, d, a, b, id, (t, vt));
+            visit::visit_fn(fk, d, a, b, id, (copy t, vt));
         },
 
         visit_struct_field: |f, (t, vt)| {
-            vfn(f.node.id, t);
+            vfn(f.node.id, copy t);
             visit::visit_struct_field(f, (t, vt));
         },
 
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 1704b4ef6c5..e67ca5260b8 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -318,7 +318,7 @@ pub fn expect<T:Copy>(diag: @span_handler,
                        opt: Option<T>,
                        msg: &fn() -> ~str) -> T {
     match opt {
-       Some(ref t) => (*t),
+       Some(ref t) => copy *t,
        None => diag.handler().bug(msg())
     }
 }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 7eec9e2ee89..e72d9b502dc 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -322,7 +322,7 @@ pub fn commasep<IN: Copy>(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN)) {
     let mut first = true;
     for elts.each |elt| {
         if first { first = false; } else { word_space(s, ","); }
-        op(s, *elt);
+        op(s, copy *elt);
     }
     end(s);
 }
@@ -334,13 +334,13 @@ pub fn commasep_cmnt<IN: Copy>(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN),
     let len = elts.len();
     let mut i = 0u;
     for elts.each |elt| {
-        maybe_print_comment(s, get_span(*elt).hi);
-        op(s, *elt);
+        maybe_print_comment(s, get_span(copy *elt).hi);
+        op(s, copy *elt);
         i += 1u;
         if i < len {
             word(s.s, ",");
-            maybe_print_trailing_comment(s, get_span(*elt),
-                                         Some(get_span(elts[i]).hi));
+            maybe_print_trailing_comment(s, get_span(copy *elt),
+                                         Some(get_span(copy elts[i]).hi));
             space_if_not_bol(s);
         }
     }
@@ -2118,7 +2118,7 @@ pub fn print_string(s: @ps, st: &str) {
 pub fn to_str<T: Copy>(t: T, f: @fn(@ps, T), intr: @ident_interner) -> ~str {
     do io::with_str_writer |wr| {
         let s = rust_printer(wr, intr);
-        f(s, t);
+        f(s, copy t);
         eof(s.s);
     }
 }
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index d4f183ada7b..bd5c178e7fe 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -36,7 +36,7 @@ impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
 
     pub fn prefill(init: &[T]) -> Interner<T> {
         let rv = Interner::new();
-        for init.each() |v| { rv.intern(*v); }
+        for init.each() |v| { rv.intern(copy *v); }
         rv
     }
 
@@ -48,7 +48,7 @@ impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
 
         let vect = &mut *self.vect;
         let new_idx = vect.len();
-        self.map.insert(val, new_idx);
+        self.map.insert(copy val, new_idx);
         vect.push(val);
         new_idx
     }
@@ -63,7 +63,7 @@ impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
         new_idx
     }
 
-    pub fn get(&self, idx: uint) -> T { self.vect[idx] }
+    pub fn get(&self, idx: uint) -> T { copy self.vect[idx] }
 
     pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() }
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 6e753a8cc58..f24c393d7b4 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -127,15 +127,15 @@ pub fn visit_crate<E: Copy>(c: &crate, (e, v): (E, vt<E>)) {
 }
 
 pub fn visit_mod<E: Copy>(m: &_mod, _sp: span, _id: node_id, (e, v): (E, vt<E>)) {
-    for m.view_items.each |vi| { (v.visit_view_item)(*vi, (e, v)); }
-    for m.items.each |i| { (v.visit_item)(*i, (e, v)); }
+    for m.view_items.each |vi| { (v.visit_view_item)(*vi, (copy e, v)); }
+    for m.items.each |i| { (v.visit_item)(*i, (copy e, v)); }
 }
 
 pub fn visit_view_item<E>(_vi: @view_item, (_e, _v): (E, vt<E>)) { }
 
 pub fn visit_local<E: Copy>(loc: @local, (e, v): (E, vt<E>)) {
-    (v.visit_pat)(loc.node.pat, (e, v));
-    (v.visit_ty)(loc.node.ty, (e, v));
+    (v.visit_pat)(loc.node.pat, (copy e, v));
+    (v.visit_ty)(loc.node.ty, (copy e, v));
     match loc.node.init {
       None => (),
       Some(ex) => (v.visit_expr)(ex, (e, v))
@@ -149,8 +149,8 @@ fn visit_trait_ref<E: Copy>(tref: @ast::trait_ref, (e, v): (E, vt<E>)) {
 pub fn visit_item<E: Copy>(i: @item, (e, v): (E, vt<E>)) {
     match i.node {
         item_const(t, ex) => {
-            (v.visit_ty)(t, (e, v));
-            (v.visit_expr)(ex, (e, v));
+            (v.visit_ty)(t, (copy e, v));
+            (v.visit_expr)(ex, (copy e, v));
         }
         item_fn(ref decl, purity, abi, ref generics, ref body) => {
             (v.visit_fn)(
@@ -170,15 +170,15 @@ pub fn visit_item<E: Copy>(i: @item, (e, v): (E, vt<E>)) {
         }
         item_mod(ref m) => (v.visit_mod)(m, i.span, i.id, (e, v)),
         item_foreign_mod(ref nm) => {
-            for nm.view_items.each |vi| { (v.visit_view_item)(*vi, (e, v)); }
-            for nm.items.each |ni| { (v.visit_foreign_item)(*ni, (e, v)); }
+            for nm.view_items.each |vi| { (v.visit_view_item)(*vi, (copy e, v)); }
+            for nm.items.each |ni| { (v.visit_foreign_item)(*ni, (copy e, v)); }
         }
         item_ty(t, ref tps) => {
-            (v.visit_ty)(t, (e, v));
+            (v.visit_ty)(t, (copy e, v));
             (v.visit_generics)(tps, (e, v));
         }
         item_enum(ref enum_definition, ref tps) => {
-            (v.visit_generics)(tps, (e, v));
+            (v.visit_generics)(tps, (copy e, v));
             visit_enum_def(
                 enum_definition,
                 tps,
@@ -186,24 +186,24 @@ pub fn visit_item<E: Copy>(i: @item, (e, v): (E, vt<E>)) {
             );
         }
         item_impl(ref tps, ref traits, ty, ref methods) => {
-            (v.visit_generics)(tps, (e, v));
+            (v.visit_generics)(tps, (copy e, v));
             for traits.iter().advance |&p| {
-                visit_trait_ref(p, (e, v));
+                visit_trait_ref(p, (copy e, v));
             }
-            (v.visit_ty)(ty, (e, v));
+            (v.visit_ty)(ty, (copy e, v));
             for methods.each |m| {
-                visit_method_helper(*m, (e, v))
+                visit_method_helper(*m, (copy e, v))
             }
         }
         item_struct(struct_def, ref generics) => {
-            (v.visit_generics)(generics, (e, v));
+            (v.visit_generics)(generics, (copy e, v));
             (v.visit_struct_def)(struct_def, i.ident, generics, i.id, (e, v));
         }
         item_trait(ref generics, ref traits, ref methods) => {
-            (v.visit_generics)(generics, (e, v));
-            for traits.each |p| { visit_path(p.path, (e, v)); }
+            (v.visit_generics)(generics, (copy e, v));
+            for traits.each |p| { visit_path(p.path, (copy e, v)); }
             for methods.each |m| {
-                (v.visit_trait_method)(m, (e, v));
+                (v.visit_trait_method)(m, (copy e, v));
             }
         }
         item_mac(ref m) => visit_mac(m, (e, v))
@@ -216,15 +216,19 @@ pub fn visit_enum_def<E: Copy>(enum_definition: &ast::enum_def,
     for enum_definition.variants.each |vr| {
         match vr.node.kind {
             tuple_variant_kind(ref variant_args) => {
-                for variant_args.each |va| { (v.visit_ty)(va.ty, (e, v)); }
+                for variant_args.each |va| {
+                    (v.visit_ty)(va.ty, (copy e, v));
+                }
             }
             struct_variant_kind(struct_def) => {
                 (v.visit_struct_def)(struct_def, vr.node.name, tps,
-                                   vr.node.id, (e, v));
+                                     vr.node.id, (copy e, v));
             }
         }
         // Visit the disr expr if it exists
-        for vr.node.disr_expr.iter().advance |ex| { (v.visit_expr)(*ex, (e, v)) }
+        for vr.node.disr_expr.iter().advance |ex| {
+            (v.visit_expr)(*ex, (copy e, v))
+        }
     }
 }
 
@@ -238,71 +242,75 @@ pub fn visit_ty<E: Copy>(t: @Ty, (e, v): (E, vt<E>)) {
         },
         ty_tup(ref ts) => {
             for ts.each |tt| {
-                (v.visit_ty)(*tt, (e, v));
+                (v.visit_ty)(*tt, (copy e, v));
             }
         },
         ty_closure(ref f) => {
-            for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (e, v)); }
+            for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy e, v)); }
             (v.visit_ty)(f.decl.output, (e, v));
         },
         ty_bare_fn(ref f) => {
-            for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (e, v)); }
+            for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy e, v)); }
             (v.visit_ty)(f.decl.output, (e, v));
         },
         ty_path(p, _) => visit_path(p, (e, v)),
         ty_fixed_length_vec(ref mt, ex) => {
-            (v.visit_ty)(mt.ty, (e, v));
-            (v.visit_expr)(ex, (e, v));
+            (v.visit_ty)(mt.ty, (copy e, v));
+            (v.visit_expr)(ex, (copy e, v));
         },
         ty_nil | ty_bot | ty_mac(_) | ty_infer => ()
     }
 }
 
 pub fn visit_path<E: Copy>(p: @Path, (e, v): (E, vt<E>)) {
-    for p.types.each |tp| { (v.visit_ty)(*tp, (e, v)); }
+    for p.types.each |tp| { (v.visit_ty)(*tp, (copy e, v)); }
 }
 
 pub fn visit_pat<E: Copy>(p: @pat, (e, v): (E, vt<E>)) {
     match p.node {
         pat_enum(path, ref children) => {
-            visit_path(path, (e, v));
+            visit_path(path, (copy e, v));
             for children.iter().advance |children| {
-                for children.iter().advance |child| { (v.visit_pat)(*child, (e, v)); }
+                for children.iter().advance |child| {
+                    (v.visit_pat)(*child, (copy e, v));
+                }
             }
         }
         pat_struct(path, ref fields, _) => {
-            visit_path(path, (e, v));
+            visit_path(path, (copy e, v));
             for fields.each |f| {
-                (v.visit_pat)(f.pat, (e, v));
+                (v.visit_pat)(f.pat, (copy e, v));
             }
         }
         pat_tup(ref elts) => {
             for elts.each |elt| {
-                (v.visit_pat)(*elt, (e, v))
+                (v.visit_pat)(*elt, (copy e, v))
             }
         },
         pat_box(inner) | pat_uniq(inner) | pat_region(inner) => {
             (v.visit_pat)(inner, (e, v))
         },
         pat_ident(_, path, ref inner) => {
-            visit_path(path, (e, v));
-            for inner.iter().advance |subpat| { (v.visit_pat)(*subpat, (e, v)) }
+            visit_path(path, (copy e, v));
+            for inner.iter().advance |subpat| {
+                (v.visit_pat)(*subpat, (copy e, v))
+            }
         }
         pat_lit(ex) => (v.visit_expr)(ex, (e, v)),
         pat_range(e1, e2) => {
-            (v.visit_expr)(e1, (e, v));
+            (v.visit_expr)(e1, (copy e, v));
             (v.visit_expr)(e2, (e, v));
         }
         pat_wild => (),
         pat_vec(ref before, ref slice, ref after) => {
             for before.each |elt| {
-                (v.visit_pat)(*elt, (e, v));
+                (v.visit_pat)(*elt, (copy e, v));
             }
             for slice.iter().advance |elt| {
-                (v.visit_pat)(*elt, (e, v));
+                (v.visit_pat)(*elt, (copy e, v));
             }
             for after.each |tail| {
-                (v.visit_pat)(*tail, (e, v));
+                (v.visit_pat)(*tail, (copy e, v));
             }
         }
     }
@@ -311,7 +319,7 @@ pub fn visit_pat<E: Copy>(p: @pat, (e, v): (E, vt<E>)) {
 pub fn visit_foreign_item<E: Copy>(ni: @foreign_item, (e, v): (E, vt<E>)) {
     match ni.node {
         foreign_item_fn(ref fd, _, ref generics) => {
-            visit_fn_decl(fd, (e, v));
+            visit_fn_decl(fd, (copy e, v));
             (v.visit_generics)(generics, (e, v));
         }
         foreign_item_const(t) => {
@@ -324,7 +332,7 @@ pub fn visit_ty_param_bounds<E: Copy>(bounds: @OptVec<TyParamBound>,
                                       (e, v): (E, vt<E>)) {
     for bounds.each |bound| {
         match *bound {
-            TraitTyParamBound(ty) => visit_trait_ref(ty, (e, v)),
+            TraitTyParamBound(ty) => visit_trait_ref(ty, (copy e, v)),
             RegionTyParamBound => {}
         }
     }
@@ -332,14 +340,14 @@ pub fn visit_ty_param_bounds<E: Copy>(bounds: @OptVec<TyParamBound>,
 
 pub fn visit_generics<E: Copy>(generics: &Generics, (e, v): (E, vt<E>)) {
     for generics.ty_params.each |tp| {
-        visit_ty_param_bounds(tp.bounds, (e, v));
+        visit_ty_param_bounds(tp.bounds, (copy e, v));
     }
 }
 
 pub fn visit_fn_decl<E: Copy>(fd: &fn_decl, (e, v): (E, vt<E>)) {
     for fd.inputs.each |a| {
-        (v.visit_pat)(a.pat, (e, v));
-        (v.visit_ty)(a.ty, (e, v));
+        (v.visit_pat)(a.pat, (copy e, v));
+        (v.visit_ty)(a.ty, (copy e, v));
     }
     (v.visit_ty)(fd.output, (e, v));
 }
@@ -365,15 +373,15 @@ pub fn visit_method_helper<E: Copy>(m: &method, (e, v): (E, vt<E>)) {
 
 pub fn visit_fn<E: Copy>(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span,
                          _id: node_id, (e, v): (E, vt<E>)) {
-    visit_fn_decl(decl, (e, v));
+    visit_fn_decl(decl, (copy e, v));
     let generics = generics_of_fn(fk);
-    (v.visit_generics)(&generics, (e, v));
+    (v.visit_generics)(&generics, (copy e, v));
     (v.visit_block)(body, (e, v));
 }
 
 pub fn visit_ty_method<E: Copy>(m: &ty_method, (e, v): (E, vt<E>)) {
-    for m.decl.inputs.each |a| { (v.visit_ty)(a.ty, (e, v)); }
-    (v.visit_generics)(&m.generics, (e, v));
+    for m.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy e, v)); }
+    (v.visit_generics)(&m.generics, (copy e, v));
     (v.visit_ty)(m.decl.output, (e, v));
 }
 
@@ -392,7 +400,7 @@ pub fn visit_struct_def<E: Copy>(
     (e, v): (E, vt<E>)
 ) {
     for sd.fields.each |f| {
-        (v.visit_struct_field)(*f, (e, v));
+        (v.visit_struct_field)(*f, (copy e, v));
     }
 }
 
@@ -406,10 +414,10 @@ pub fn visit_struct_method<E: Copy>(m: @method, (e, v): (E, vt<E>)) {
 
 pub fn visit_block<E: Copy>(b: &blk, (e, v): (E, vt<E>)) {
     for b.node.view_items.each |vi| {
-        (v.visit_view_item)(*vi, (e, v));
+        (v.visit_view_item)(*vi, (copy e, v));
     }
     for b.node.stmts.each |s| {
-        (v.visit_stmt)(*s, (e, v));
+        (v.visit_stmt)(*s, (copy e, v));
     }
     visit_expr_opt(b.node.expr, (e, v));
 }
@@ -435,7 +443,7 @@ pub fn visit_expr_opt<E>(eo: Option<@expr>, (e, v): (E, vt<E>)) {
 }
 
 pub fn visit_exprs<E: Copy>(exprs: &[@expr], (e, v): (E, vt<E>)) {
-    for exprs.each |ex| { (v.visit_expr)(*ex, (e, v)); }
+    for exprs.each |ex| { (v.visit_expr)(*ex, (copy e, v)); }
 }
 
 pub fn visit_mac<E>(_m: &mac, (_e, _v): (E, vt<E>)) {
@@ -444,53 +452,57 @@ pub fn visit_mac<E>(_m: &mac, (_e, _v): (E, vt<E>)) {
 
 pub fn visit_expr<E: Copy>(ex: @expr, (e, v): (E, vt<E>)) {
     match ex.node {
-        expr_vstore(x, _) => (v.visit_expr)(x, (e, v)),
-        expr_vec(ref es, _) => visit_exprs(*es, (e, v)),
+        expr_vstore(x, _) => (v.visit_expr)(x, (copy e, v)),
+        expr_vec(ref es, _) => visit_exprs(*es, (copy e, v)),
         expr_repeat(element, count, _) => {
-            (v.visit_expr)(element, (e, v));
-            (v.visit_expr)(count, (e, v));
+            (v.visit_expr)(element, (copy e, v));
+            (v.visit_expr)(count, (copy e, v));
         }
         expr_struct(p, ref flds, base) => {
-            visit_path(p, (e, v));
-            for flds.each |f| { (v.visit_expr)(f.node.expr, (e, v)); }
-            visit_expr_opt(base, (e, v));
+            visit_path(p, (copy e, v));
+            for flds.each |f| {
+                (v.visit_expr)(f.node.expr, (copy e, v));
+            }
+            visit_expr_opt(base, (copy e, v));
         }
         expr_tup(ref elts) => {
-            for elts.each |el| { (v.visit_expr)(*el, (e, v)) }
+            for elts.each |el| { (v.visit_expr)(*el, (copy e, v)) }
         }
         expr_call(callee, ref args, _) => {
-            visit_exprs(*args, (e, v));
-            (v.visit_expr)(callee, (e, v));
+            visit_exprs(*args, (copy e, v));
+            (v.visit_expr)(callee, (copy e, v));
         }
         expr_method_call(_, callee, _, ref tys, ref args, _) => {
-            visit_exprs(*args, (e, v));
-            for tys.each |tp| { (v.visit_ty)(*tp, (e, v)); }
-            (v.visit_expr)(callee, (e, v));
+            visit_exprs(*args, (copy e, v));
+            for tys.each |tp| {
+                (v.visit_ty)(*tp, (copy e, v));
+            }
+            (v.visit_expr)(callee, (copy e, v));
         }
         expr_binary(_, _, a, b) => {
-            (v.visit_expr)(a, (e, v));
-            (v.visit_expr)(b, (e, v));
+            (v.visit_expr)(a, (copy e, v));
+            (v.visit_expr)(b, (copy e, v));
         }
         expr_addr_of(_, x) | expr_unary(_, _, x) |
-        expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (e, v)),
+        expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (copy e, v)),
         expr_lit(_) => (),
         expr_cast(x, t) => {
-            (v.visit_expr)(x, (e, v));
-            (v.visit_ty)(t, (e, v));
+            (v.visit_expr)(x, (copy e, v));
+            (v.visit_ty)(t, (copy e, v));
         }
         expr_if(x, ref b, eo) => {
-            (v.visit_expr)(x, (e, v));
-            (v.visit_block)(b, (e, v));
-            visit_expr_opt(eo, (e, v));
+            (v.visit_expr)(x, (copy e, v));
+            (v.visit_block)(b, (copy e, v));
+            visit_expr_opt(eo, (copy e, v));
         }
         expr_while(x, ref b) => {
-            (v.visit_expr)(x, (e, v));
-            (v.visit_block)(b, (e, v));
+            (v.visit_expr)(x, (copy e, v));
+            (v.visit_block)(b, (copy e, v));
         }
-        expr_loop(ref b, _) => (v.visit_block)(b, (e, v)),
+        expr_loop(ref b, _) => (v.visit_block)(b, (copy e, v)),
         expr_match(x, ref arms) => {
-            (v.visit_expr)(x, (e, v));
-            for arms.each |a| { (v.visit_arm)(a, (e, v)); }
+            (v.visit_expr)(x, (copy e, v));
+            for arms.each |a| { (v.visit_arm)(a, (copy e, v)); }
         }
         expr_fn_block(ref decl, ref body) => {
             (v.visit_fn)(
@@ -499,44 +511,46 @@ pub fn visit_expr<E: Copy>(ex: @expr, (e, v): (E, vt<E>)) {
                 body,
                 ex.span,
                 ex.id,
-                (e, v)
+                (copy e, v)
             );
         }
-        expr_block(ref b) => (v.visit_block)(b, (e, v)),
+        expr_block(ref b) => (v.visit_block)(b, (copy e, v)),
         expr_assign(a, b) => {
-            (v.visit_expr)(b, (e, v));
-            (v.visit_expr)(a, (e, v));
+            (v.visit_expr)(b, (copy e, v));
+            (v.visit_expr)(a, (copy e, v));
         }
-        expr_copy(a) => (v.visit_expr)(a, (e, v)),
+        expr_copy(a) => (v.visit_expr)(a, (copy e, v)),
         expr_assign_op(_, _, a, b) => {
-            (v.visit_expr)(b, (e, v));
-            (v.visit_expr)(a, (e, v));
+            (v.visit_expr)(b, (copy e, v));
+            (v.visit_expr)(a, (copy e, v));
         }
         expr_field(x, _, ref tys) => {
-            (v.visit_expr)(x, (e, v));
-            for tys.each |tp| { (v.visit_ty)(*tp, (e, v)); }
+            (v.visit_expr)(x, (copy e, v));
+            for tys.each |tp| {
+                (v.visit_ty)(*tp, (copy e, v));
+            }
         }
         expr_index(_, a, b) => {
-            (v.visit_expr)(a, (e, v));
-            (v.visit_expr)(b, (e, v));
+            (v.visit_expr)(a, (copy e, v));
+            (v.visit_expr)(b, (copy e, v));
         }
-        expr_path(p) => visit_path(p, (e, v)),
+        expr_path(p) => visit_path(p, (copy e, v)),
         expr_self => (),
         expr_break(_) => (),
         expr_again(_) => (),
-        expr_ret(eo) => visit_expr_opt(eo, (e, v)),
+        expr_ret(eo) => visit_expr_opt(eo, (copy e, v)),
         expr_log(lv, x) => {
-            (v.visit_expr)(lv, (e, v));
-            (v.visit_expr)(x, (e, v));
+            (v.visit_expr)(lv, (copy e, v));
+            (v.visit_expr)(x, (copy e, v));
         }
-        expr_mac(ref mac) => visit_mac(mac, (e, v)),
-        expr_paren(x) => (v.visit_expr)(x, (e, v)),
+        expr_mac(ref mac) => visit_mac(mac, (copy e, v)),
+        expr_paren(x) => (v.visit_expr)(x, (copy e, v)),
         expr_inline_asm(ref a) => {
             for a.inputs.each |&(_, in)| {
-                (v.visit_expr)(in, (e, v));
+                (v.visit_expr)(in, (copy e, v));
             }
             for a.outputs.each |&(_, out)| {
-                (v.visit_expr)(out, (e, v));
+                (v.visit_expr)(out, (copy e, v));
             }
         }
     }
@@ -544,9 +558,9 @@ pub fn visit_expr<E: Copy>(ex: @expr, (e, v): (E, vt<E>)) {
 }
 
 pub fn visit_arm<E: Copy>(a: &arm, (e, v): (E, vt<E>)) {
-    for a.pats.iter().advance |p| { (v.visit_pat)(*p, (e, v)); }
-    visit_expr_opt(a.guard, (e, v));
-    (v.visit_block)(&a.body, (e, v));
+    for a.pats.iter().advance |p| { (v.visit_pat)(*p, (copy e, v)); }
+    visit_expr_opt(a.guard, (copy e, v));
+    (v.visit_block)(&a.body, (copy e, v));
 }
 
 // Simpler, non-context passing interface. Always walks the whole tree, simply