summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-07-02 12:47:32 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-07-17 14:57:51 -0700
commit99b33f721954bc5290f9201c8f64003c294d0571 (patch)
tree786c9bf75d54512d0a80f6975ad40516ab432c3a /src/libsyntax
parentb4e674f6e662bc80f2e7a5a1a9834f2152f08d32 (diff)
downloadrust-99b33f721954bc5290f9201c8f64003c294d0571.tar.gz
rust-99b33f721954bc5290f9201c8f64003c294d0571.zip
librustc: Remove all uses of "copy".
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/abi.rs2
-rw-r--r--src/libsyntax/ast.rs174
-rw-r--r--src/libsyntax/ast_map.rs38
-rw-r--r--src/libsyntax/ast_util.rs96
-rw-r--r--src/libsyntax/attr.rs8
-rw-r--r--src/libsyntax/codemap.rs11
-rw-r--r--src/libsyntax/diagnostic.rs8
-rw-r--r--src/libsyntax/ext/base.rs4
-rw-r--r--src/libsyntax/ext/build.rs6
-rw-r--r--src/libsyntax/ext/deriving/generic.rs25
-rw-r--r--src/libsyntax/ext/deriving/iter_bytes.rs5
-rw-r--r--src/libsyntax/ext/deriving/rand.rs8
-rw-r--r--src/libsyntax/ext/deriving/zero.rs2
-rw-r--r--src/libsyntax/ext/expand.rs10
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs8
-rw-r--r--src/libsyntax/ext/pipes/mod.rs2
-rw-r--r--src/libsyntax/ext/pipes/parse_proto.rs2
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs18
-rw-r--r--src/libsyntax/ext/pipes/proto.rs6
-rw-r--r--src/libsyntax/ext/quote.rs2
-rw-r--r--src/libsyntax/ext/source_util.rs2
-rw-r--r--src/libsyntax/ext/trace_macros.rs6
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs24
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs13
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs42
-rw-r--r--src/libsyntax/fold.rs39
-rw-r--r--src/libsyntax/opt_vec.rs4
-rw-r--r--src/libsyntax/parse/attr.rs14
-rw-r--r--src/libsyntax/parse/comments.rs4
-rw-r--r--src/libsyntax/parse/lexer.rs16
-rw-r--r--src/libsyntax/parse/mod.rs14
-rw-r--r--src/libsyntax/parse/obsolete.rs8
-rw-r--r--src/libsyntax/parse/parser.rs846
-rw-r--r--src/libsyntax/parse/token.rs10
-rw-r--r--src/libsyntax/print/pp.rs20
-rw-r--r--src/libsyntax/print/pprust.rs42
-rw-r--r--src/libsyntax/util/interner.rs12
-rw-r--r--src/libsyntax/visit.rs277
38 files changed, 1024 insertions, 804 deletions
diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs
index fadd2faf0eb..bf0dee0822f 100644
--- a/src/libsyntax/abi.rs
+++ b/src/libsyntax/abi.rs
@@ -58,7 +58,7 @@ enum AbiArchitecture {
     Archs(u32)  // Multiple architectures (bitset)
 }
 
-#[deriving(Eq, Encodable, Decodable)]
+#[deriving(Clone, Eq, Encodable, Decodable)]
 pub struct AbiSet {
     priv bits: u32   // each bit represents one of the abis below
 }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 6cf38d5ae1d..38f0b2496cb 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -24,7 +24,7 @@ use extra::serialize::{Encodable, Decodable, Encoder, Decoder};
 // table) and a SyntaxContext to track renaming and
 // macro expansion per Flatt et al., "Macros
 // That Work Together"
-#[deriving(Eq,IterBytes)]
+#[deriving(Clone, Eq, IterBytes)]
 pub struct ident { name: Name, ctxt: SyntaxContext }
 
 /// Construct an identifier with the given name and an empty context:
@@ -93,7 +93,7 @@ impl<D:Decoder> Decodable<D> for ident {
 // Functions may or may not have names.
 pub type fn_ident = Option<ident>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct Lifetime {
     id: node_id,
     span: span,
@@ -104,7 +104,7 @@ pub struct Lifetime {
 // for instance: core::cmp::Eq  .  It's represented
 // as a sequence of identifiers, along with a bunch
 // of supporting information.
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct Path {
     span: span,
     global: bool,
@@ -117,7 +117,7 @@ pub type crate_num = int;
 
 pub type node_id = int;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct def_id {
     crate: crate_num,
     node: node_id,
@@ -126,27 +126,27 @@ pub struct def_id {
 pub static local_crate: crate_num = 0;
 pub static crate_node_id: node_id = 0;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
 // The AST represents all type param bounds as types.
 // typeck::collect::compute_bounds matches these against
 // the "special" built-in traits (see middle::lang_items) and
 // detects Copy, Send, Send, and Freeze.
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum TyParamBound {
     TraitTyParamBound(trait_ref),
     RegionTyParamBound
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct TyParam {
     ident: ident,
     id: node_id,
     bounds: OptVec<TyParamBound>
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct Generics {
     lifetimes: OptVec<Lifetime>,
-    ty_params: OptVec<TyParam>
+    ty_params: OptVec<TyParam>,
 }
 
 impl Generics {
@@ -161,7 +161,7 @@ impl Generics {
     }
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum def {
     def_fn(def_id, purity),
     def_static_method(/* method */ def_id,
@@ -199,7 +199,7 @@ pub type crate_cfg = ~[@meta_item];
 
 pub type crate = spanned<crate_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct crate_ {
     module: _mod,
     attrs: ~[attribute],
@@ -208,7 +208,7 @@ pub struct crate_ {
 
 pub type meta_item = spanned<meta_item_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum meta_item_ {
     meta_word(@str),
     meta_list(@str, ~[@meta_item]),
@@ -217,7 +217,7 @@ pub enum meta_item_ {
 
 //pub type blk = spanned<blk_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
 pub struct blk {
     view_items: ~[view_item],
     stmts: ~[@stmt],
@@ -227,26 +227,26 @@ pub struct blk {
     span: span,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct pat {
     id: node_id,
     node: pat_,
     span: span,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct field_pat {
     ident: ident,
     pat: @pat,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum binding_mode {
     bind_by_ref(mutability),
     bind_infer
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum pat_ {
     pat_wild,
     // A pat_ident may either be a new bound variable,
@@ -271,10 +271,10 @@ pub enum pat_ {
     pat_vec(~[@pat], Option<@pat>, ~[@pat])
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum mutability { m_mutbl, m_imm, m_const, }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum Sigil {
     BorrowedSigil,
     OwnedSigil,
@@ -300,7 +300,7 @@ pub enum vstore {
     vstore_slice(Option<Lifetime>) // &'foo? [1,2,3,4]
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum expr_vstore {
     expr_vstore_uniq,                  // ~[1,2,3,4]
     expr_vstore_box,                   // @[1,2,3,4]
@@ -309,7 +309,7 @@ pub enum expr_vstore {
     expr_vstore_mut_slice,             // &mut [1,2,3,4]
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum binop {
     add,
     subtract,
@@ -331,7 +331,7 @@ pub enum binop {
     gt,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum unop {
     box(mutability),
     uniq,
@@ -342,7 +342,7 @@ pub enum unop {
 
 pub type stmt = spanned<stmt_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum stmt_ {
     // could be an item or a local (let) binding:
     stmt_decl(@decl, node_id),
@@ -380,14 +380,14 @@ pub enum decl_ {
     decl_item(@item),
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct arm {
     pats: ~[@pat],
     guard: Option<@expr>,
     body: blk,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct field_ {
     ident: ident,
     expr: @expr,
@@ -395,8 +395,11 @@ pub struct field_ {
 
 pub type field = spanned<field_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
-pub enum blk_check_mode { default_blk, unsafe_blk, }
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
+pub enum blk_check_mode {
+    default_blk,
+    unsafe_blk,
+}
 
 #[deriving(Eq, Encodable, Decodable,IterBytes)]
 pub struct expr {
@@ -418,14 +421,14 @@ impl expr {
     }
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum CallSugar {
     NoSugar,
     DoSugar,
     ForSugar
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum expr_ {
     expr_vstore(@expr, expr_vstore),
     expr_vec(~[@expr], mutability),
@@ -496,7 +499,7 @@ pub enum expr_ {
 // else knows what to do with them, so you'll probably get a syntax
 // error.
 //
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 #[doc="For macro invocations; parsing is delegated to the macro"]
 pub enum token_tree {
     // a single token
@@ -569,7 +572,7 @@ pub enum token_tree {
 //
 pub type matcher = spanned<matcher_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum matcher_ {
     // match one token
     match_tok(::parse::token::Token),
@@ -582,14 +585,14 @@ pub enum matcher_ {
 
 pub type mac = spanned<mac_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum mac_ {
     mac_invoc_tt(Path,~[token_tree]),   // new macro-invocation
 }
 
 pub type lit = spanned<lit_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum lit_ {
     lit_str(@str),
     lit_int(i64, int_ty),
@@ -603,7 +606,7 @@ pub enum lit_ {
 
 // NB: If you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct mt {
     ty: ~Ty,
     mutbl: mutability,
@@ -617,7 +620,7 @@ pub struct ty_field_ {
 
 pub type ty_field = spanned<ty_field_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct ty_method {
     ident: ident,
     attrs: ~[attribute],
@@ -629,17 +632,24 @@ pub struct ty_method {
     span: span,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
 // A trait method is either required (meaning it doesn't have an
 // implementation, just a signature) or provided (meaning it has a default
 // implementation).
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum trait_method {
     required(ty_method),
     provided(@method),
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
-pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
+pub enum int_ty {
+    ty_i,
+    ty_char,
+    ty_i8,
+    ty_i16,
+    ty_i32,
+    ty_i64,
+}
 
 impl ToStr for int_ty {
     fn to_str(&self) -> ~str {
@@ -647,8 +657,14 @@ impl ToStr for int_ty {
     }
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
-pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, }
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
+pub enum uint_ty {
+    ty_u,
+    ty_u8,
+    ty_u16,
+    ty_u32,
+    ty_u64,
+}
 
 impl ToStr for uint_ty {
     fn to_str(&self) -> ~str {
@@ -656,8 +672,12 @@ impl ToStr for uint_ty {
     }
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
-pub enum float_ty { ty_f, ty_f32, ty_f64, }
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
+pub enum float_ty {
+    ty_f,
+    ty_f32,
+    ty_f64,
+}
 
 impl ToStr for float_ty {
     fn to_str(&self) -> ~str {
@@ -666,7 +686,7 @@ impl ToStr for float_ty {
 }
 
 // NB Eq method appears below.
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
 pub struct Ty {
     id: node_id,
     node: ty_,
@@ -674,7 +694,7 @@ pub struct Ty {
 }
 
 // Not represented directly in the AST, referred to by name through a ty_path.
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum prim_ty {
     ty_int(int_ty),
     ty_uint(uint_ty),
@@ -683,7 +703,7 @@ pub enum prim_ty {
     ty_bool,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum Onceness {
     Once,
     Many
@@ -722,7 +742,7 @@ pub struct TyBareFn {
     decl: fn_decl
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum ty_ {
     ty_nil,
     ty_bot, /* bottom type */
@@ -743,13 +763,13 @@ pub enum ty_ {
     ty_infer,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum asm_dialect {
     asm_att,
     asm_intel
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct inline_asm {
     asm: @str,
     clobbers: @str,
@@ -760,7 +780,7 @@ pub struct inline_asm {
     dialect: asm_dialect
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct arg {
     is_mutbl: bool,
     ty: Ty,
@@ -768,14 +788,14 @@ pub struct arg {
     id: node_id,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct fn_decl {
     inputs: ~[arg],
     output: Ty,
     cf: ret_style,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum purity {
     unsafe_fn, // declared with "unsafe fn"
     impure_fn, // declared with "fn"
@@ -793,14 +813,14 @@ impl ToStr for purity {
     }
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum ret_style {
     noreturn, // functions with return type _|_ that always
               // raise an error or exit (i.e. never return to the caller)
     return_val, // everything else
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum explicit_self_ {
     sty_static,                                // no self
     sty_value,                                 // `self`
@@ -826,17 +846,20 @@ pub struct method {
     vis: visibility,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct _mod {
     view_items: ~[view_item],
     items: ~[@item],
 }
 
 // Foreign mods can be named or anonymous
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
-pub enum foreign_mod_sort { named, anonymous }
+#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
+pub enum foreign_mod_sort {
+    named,
+    anonymous,
+}
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
 pub struct foreign_mod {
     sort: foreign_mod_sort,
     abis: AbiSet,
@@ -844,24 +867,24 @@ pub struct foreign_mod {
     items: ~[@foreign_item],
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct variant_arg {
     ty: Ty,
     id: node_id,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum variant_kind {
     tuple_variant_kind(~[variant_arg]),
     struct_variant_kind(@struct_def),
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct enum_def {
     variants: ~[variant],
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct variant_ {
     name: ident,
     attrs: ~[attribute],
@@ -873,7 +896,7 @@ pub struct variant_ {
 
 pub type variant = spanned<variant_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct path_list_ident_ {
     name: ident,
     id: node_id,
@@ -883,7 +906,7 @@ pub type path_list_ident = spanned<path_list_ident_>;
 
 pub type view_path = spanned<view_path_>;
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Eq, Encodable, Decodable, IterBytes)]
 pub enum view_path_ {
 
     // quux = foo::bar::baz
@@ -900,7 +923,7 @@ pub enum view_path_ {
     view_path_list(Path, ~[path_list_ident], node_id)
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct view_item {
     node: view_item_,
     attrs: ~[attribute],
@@ -908,7 +931,7 @@ pub struct view_item {
     span: span,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum view_item_ {
     view_item_extern_mod(ident, ~[@meta_item], node_id),
     view_item_use(~[@view_path]),
@@ -920,11 +943,14 @@ pub type attribute = spanned<attribute_>;
 // Distinguishes between attributes that decorate items and attributes that
 // are contained as statements within items. These two cases need to be
 // distinguished for pretty-printing.
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
-pub enum attr_style { attr_outer, attr_inner, }
+#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
+pub enum attr_style {
+    attr_outer,
+    attr_inner,
+}
 
 // doc-comments are promoted to attributes that have is_sugared_doc = true
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
 pub struct attribute_ {
     style: attr_style,
     value: @meta_item,
@@ -938,14 +964,18 @@ pub struct attribute_ {
   If this impl is an item_impl, the impl_id is redundant (it could be the
   same as the impl's node id).
  */
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
 pub struct trait_ref {
     path: Path,
     ref_id: node_id,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
-pub enum visibility { public, private, inherited }
+#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
+pub enum visibility {
+    public,
+    private,
+    inherited,
+}
 
 impl visibility {
     pub fn inherit_from(&self, parent_visibility: visibility) -> visibility {
@@ -984,7 +1014,7 @@ pub struct struct_def {
   FIXME (#3300): Should allow items to be anonymous. Right now
   we just use dummy names for anon items.
  */
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct item {
     ident: ident,
     attrs: ~[attribute],
@@ -994,7 +1024,7 @@ pub struct item {
     span: span,
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum item_ {
     item_static(Ty, mutability, @expr),
     item_fn(fn_decl, purity, AbiSet, Generics, blk),
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 354471fc2a1..721f5108cc0 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -24,31 +24,12 @@ use std::cmp;
 use std::hashmap::HashMap;
 use std::vec;
 
+#[deriving(Clone, Eq)]
 pub enum path_elt {
     path_mod(ident),
     path_name(ident)
 }
 
-impl cmp::Eq for path_elt {
-    fn eq(&self, other: &path_elt) -> bool {
-        match (*self) {
-            path_mod(e0a) => {
-                match (*other) {
-                    path_mod(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            path_name(e0a) => {
-                match (*other) {
-                    path_name(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-        }
-    }
-    fn ne(&self, other: &path_elt) -> bool { !(*self).eq(other) }
-}
-
 pub type path = ~[path_elt];
 
 pub fn path_to_str_with_sep(p: &[path_elt], sep: &str, itr: @ident_interner)
@@ -64,7 +45,6 @@ pub fn path_to_str_with_sep(p: &[path_elt], sep: &str, itr: @ident_interner)
 
 pub fn path_ident_to_str(p: &path, i: ident, itr: @ident_interner) -> ~str {
     if p.is_empty() {
-        //FIXME /* FIXME (#2543) */ copy *i
         itr.get(i.name).to_owned()
     } else {
         fmt!("%s::%s", path_to_str(*p, itr), itr.get(i.name))
@@ -82,6 +62,7 @@ pub fn path_elt_to_str(pe: path_elt, itr: @ident_interner) -> ~str {
     }
 }
 
+#[deriving(Clone)]
 pub enum ast_node {
     node_item(@item, @path),
     node_foreign_item(@foreign_item, AbiSet, visibility, @path),
@@ -109,7 +90,7 @@ pub struct Ctx {
 pub type vt = visit::vt<@mut Ctx>;
 
 pub fn extend(cx: @mut Ctx, elt: ident) -> @path {
-    @(vec::append(copy cx.path, [path_name(elt)]))
+    @(vec::append(cx.path.clone(), [path_name(elt)]))
 }
 
 pub fn mk_ast_map_visitor() -> vt {
@@ -149,7 +130,7 @@ pub fn map_decoded_item(diag: @span_handler,
     // variables that are simultaneously in scope).
     let cx = @mut Ctx {
         map: map,
-        path: copy path,
+        path: path.clone(),
         diag: diag,
     };
     let v = mk_ast_map_visitor();
@@ -190,7 +171,7 @@ pub fn map_fn(
 }
 
 pub fn map_block(b: &blk, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) {
-    cx.map.insert(b.id, node_block(/* FIXME (#2543) */ copy *b));
+    cx.map.insert(b.id, node_block(/* FIXME (#2543) */ (*b).clone()));
     visit::visit_block(b, (cx, v));
 }
 
@@ -216,7 +197,7 @@ pub fn map_method(impl_did: def_id, impl_path: @path,
 }
 
 pub fn map_item(i: @item, (cx, v): (@mut Ctx, visit::vt<@mut Ctx>)) {
-    let item_path = @/* FIXME (#2543) */ copy cx.path;
+    let item_path = @/* FIXME (#2543) */ cx.path.clone();
     cx.map.insert(i.id, node_item(i, item_path));
     match i.node {
         item_impl(_, _, _, ref ms) => {
@@ -228,7 +209,8 @@ pub fn map_item(i: @item, (cx, v): (@mut Ctx, visit::vt<@mut Ctx>)) {
         item_enum(ref enum_definition, _) => {
             for (*enum_definition).variants.iter().advance |v| {
                 cx.map.insert(v.node.id, node_variant(
-                    /* FIXME (#2543) */ copy *v, i,
+                    /* FIXME (#2543) */ (*v).clone(),
+                    i,
                     extend(cx, i.ident)));
             }
         }
@@ -251,7 +233,7 @@ pub fn map_item(i: @item, (cx, v): (@mut Ctx, visit::vt<@mut Ctx>)) {
                             extend(cx, i.ident)
                         } else {
                             // Anonymous extern mods go in the parent scope
-                            @copy cx.path
+                            @cx.path.clone()
                         }
                     )
                 );
@@ -275,7 +257,7 @@ pub fn map_item(i: @item, (cx, v): (@mut Ctx, visit::vt<@mut Ctx>)) {
                 let d_id = ast_util::local_def(i.id);
                 cx.map.insert(
                     id,
-                    node_trait_method(@copy *tm, d_id, item_path)
+                    node_trait_method(@(*tm).clone(), d_id, item_path)
                 );
             }
         }
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index feadf3fdbf3..843fd4bdba2 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -238,7 +238,11 @@ pub fn is_unguarded(a: &arm) -> bool {
 }
 
 pub fn unguarded_pat(a: &arm) -> Option<~[@pat]> {
-    if is_unguarded(a) { Some(/* FIXME (#2543) */ copy a.pats) } else { None }
+    if is_unguarded(a) {
+        Some(/* FIXME (#2543) */ a.pats.clone())
+    } else {
+        None
+    }
 }
 
 pub fn public_methods(ms: ~[@method]) -> ~[@method] {
@@ -254,14 +258,14 @@ pub fn public_methods(ms: ~[@method]) -> ~[@method] {
 // a default, pull out the useful fields to make a ty_method
 pub fn trait_method_to_ty_method(method: &trait_method) -> ty_method {
     match *method {
-        required(ref m) => copy *m,
+        required(ref m) => (*m).clone(),
         provided(ref m) => {
             ty_method {
                 ident: m.ident,
-                attrs: copy m.attrs,
+                attrs: m.attrs.clone(),
                 purity: m.purity,
-                decl: copy m.decl,
-                generics: copy m.generics,
+                decl: m.decl.clone(),
+                generics: m.generics.clone(),
                 explicit_self: m.explicit_self,
                 id: m.id,
                 span: m.span,
@@ -276,7 +280,7 @@ pub fn split_trait_methods(trait_methods: &[trait_method])
     let mut provd = ~[];
     for trait_methods.iter().advance |trt_method| {
         match *trt_method {
-          required(ref tm) => reqd.push(copy *tm),
+          required(ref tm) => reqd.push((*tm).clone()),
           provided(m) => provd.push(m)
         }
     };
@@ -293,7 +297,7 @@ pub fn struct_field_visibility(field: ast::struct_field) -> visibility {
 pub trait inlined_item_utils {
     fn ident(&self) -> ident;
     fn id(&self) -> ast::node_id;
-    fn accept<E: Copy>(&self, e: E, v: visit::vt<E>);
+    fn accept<E: Clone>(&self, e: E, v: visit::vt<E>);
 }
 
 impl inlined_item_utils for inlined_item {
@@ -313,7 +317,7 @@ impl inlined_item_utils for inlined_item {
         }
     }
 
-    fn accept<E: Copy>(&self, e: E, v: visit::vt<E>) {
+    fn accept<E: Clone>(&self, e: E, v: visit::vt<E>) {
         match *self {
             ii_item(i) => (v.visit_item)(i, (e, v)),
             ii_foreign(i) => (v.visit_foreign_item)(i, (e, v)),
@@ -385,33 +389,33 @@ impl id_range {
     }
 }
 
-pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
+pub fn id_visitor<T: Clone>(vfn: @fn(node_id, T)) -> visit::vt<T> {
     let visit_generics: @fn(&Generics, T) = |generics, t| {
         for generics.ty_params.iter().advance |p| {
-            vfn(p.id, copy t);
+            vfn(p.id, t.clone());
         }
         for generics.lifetimes.iter().advance |p| {
-            vfn(p.id, copy t);
+            vfn(p.id, t.clone());
         }
     };
     visit::mk_vt(@visit::Visitor {
-        visit_mod: |m, sp, id, (t, vt)| {
-            vfn(id, copy t);
+        visit_mod: |m, sp, id, (t, vt): (T, visit::vt<T>)| {
+            vfn(id, t.clone());
             visit::visit_mod(m, sp, id, (t, vt));
         },
 
         visit_view_item: |vi, (t, vt)| {
             match vi.node {
-              view_item_extern_mod(_, _, id) => vfn(id, copy t),
+              view_item_extern_mod(_, _, id) => vfn(id, t.clone()),
               view_item_use(ref vps) => {
                   for vps.iter().advance |vp| {
                       match vp.node {
-                          view_path_simple(_, _, id) => vfn(id, copy t),
-                          view_path_glob(_, id) => vfn(id, copy t),
+                          view_path_simple(_, _, id) => vfn(id, t.clone()),
+                          view_path_glob(_, id) => vfn(id, t.clone()),
                           view_path_list(_, ref paths, id) => {
-                              vfn(id, copy t);
+                              vfn(id, t.clone());
                               for paths.iter().advance |p| {
-                                  vfn(p.node.id, copy t);
+                                  vfn(p.node.id, t.clone());
                               }
                           }
                       }
@@ -422,34 +426,36 @@ pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
         },
 
         visit_foreign_item: |ni, (t, vt)| {
-            vfn(ni.id, copy t);
+            vfn(ni.id, t.clone());
             visit::visit_foreign_item(ni, (t, vt));
         },
 
         visit_item: |i, (t, vt)| {
-            vfn(i.id, copy t);
+            vfn(i.id, t.clone());
             match i.node {
               item_enum(ref enum_definition, _) =>
-                for (*enum_definition).variants.iter().advance |v| { vfn(v.node.id, copy t); },
+                for (*enum_definition).variants.iter().advance |v| {
+                    vfn(v.node.id, t.clone());
+                },
               _ => ()
             }
             visit::visit_item(i, (t, vt));
         },
 
         visit_local: |l, (t, vt)| {
-            vfn(l.node.id, copy t);
+            vfn(l.node.id, t.clone());
             visit::visit_local(l, (t, vt));
         },
         visit_block: |b, (t, vt)| {
-            vfn(b.id, copy t);
+            vfn(b.id, t.clone());
             visit::visit_block(b, (t, vt));
         },
         visit_stmt: |s, (t, vt)| {
-            vfn(ast_util::stmt_id(s), copy t);
+            vfn(ast_util::stmt_id(s), t.clone());
             visit::visit_stmt(s, (t, vt));
         },
         visit_pat: |p, (t, vt)| {
-            vfn(p.id, copy t);
+            vfn(p.id, t.clone());
             visit::visit_pat(p, (t, vt));
         },
 
@@ -457,37 +463,37 @@ 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, copy t);
+                    vfn(*callee_id, t.clone());
                 }
             }
-            vfn(e.id, copy t);
+            vfn(e.id, t.clone());
             visit::visit_expr(e, (t, vt));
         },
 
         visit_ty: |ty, (t, vt)| {
-            vfn(ty.id, copy t);
+            vfn(ty.id, t.clone());
             match ty.node {
-              ty_path(_, _, id) => vfn(id, copy t),
+              ty_path(_, _, id) => vfn(id, t.clone()),
               _ => { /* fall through */ }
             }
             visit::visit_ty(ty, (t, vt));
         },
 
         visit_generics: |generics, (t, vt)| {
-            visit_generics(generics, copy t);
+            visit_generics(generics, t.clone());
             visit::visit_generics(generics, (t, vt));
         },
 
         visit_fn: |fk, d, a, b, id, (t, vt)| {
-            vfn(id, copy t);
+            vfn(id, t.clone());
 
             match *fk {
                 visit::fk_item_fn(_, generics, _, _) => {
-                    visit_generics(generics, copy t);
+                    visit_generics(generics, t.clone());
                 }
                 visit::fk_method(_, generics, m) => {
-                    vfn(m.self_id, copy t);
-                    visit_generics(generics, copy t);
+                    vfn(m.self_id, t.clone());
+                    visit_generics(generics, t.clone());
                 }
                 visit::fk_anon(_) |
                 visit::fk_fn_block => {
@@ -495,13 +501,13 @@ pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
             }
 
             for d.inputs.iter().advance |arg| {
-                vfn(arg.id, copy t)
+                vfn(arg.id, t.clone())
             }
-            visit::visit_fn(fk, d, a, b, id, (copy t, vt));
+            visit::visit_fn(fk, d, a, b, id, (t.clone(), vt));
         },
 
         visit_struct_field: |f, (t, vt)| {
-            vfn(f.node.id, copy t);
+            vfn(f.node.id, t.clone());
             visit::visit_struct_field(f, (t, vt));
         },
 
@@ -800,19 +806,19 @@ mod test {
     #[test] fn xorpush_test () {
         let mut s = ~[];
         xorPush(&mut s,14);
-        assert_eq!(copy s,~[14]);
+        assert_eq!(s.clone(),~[14]);
         xorPush(&mut s,14);
-        assert_eq!(copy s,~[]);
+        assert_eq!(s.clone(),~[]);
         xorPush(&mut s,14);
-        assert_eq!(copy s,~[14]);
+        assert_eq!(s.clone(),~[14]);
         xorPush(&mut s,15);
-        assert_eq!(copy s,~[14,15]);
+        assert_eq!(s.clone(),~[14,15]);
         xorPush (&mut s,16);
-        assert_eq!(copy s,~[14,15,16]);
+        assert_eq!(s.clone(),~[14,15,16]);
         xorPush (&mut s,16);
-        assert_eq!(copy s,~[14,15]);
+        assert_eq!(s.clone(),~[14,15]);
         xorPush (&mut s,15);
-        assert_eq!(copy s,~[14]);
+        assert_eq!(s.clone(),~[14]);
     }
 
     // convert a list of uints to an @[ident]
@@ -868,7 +874,7 @@ mod test {
         let mut t = new_sctable_internal();
 
         let test_sc = ~[M(3),R(id(101,0),14),M(9)];
-        assert_eq!(unfold_test_sc(copy test_sc,empty_ctxt,&mut t),4);
+        assert_eq!(unfold_test_sc(test_sc.clone(),empty_ctxt,&mut t),4);
         assert_eq!(t.table[2],Mark(9,0));
         assert_eq!(t.table[3],Rename(id(101,0),14,2));
         assert_eq!(t.table[4],Mark(3,3));
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 18bef1ea17e..7dd01a54f7a 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -116,7 +116,7 @@ pub fn get_meta_item_value_str(meta: @ast::meta_item) -> Option<@str> {
 pub fn get_meta_item_list(meta: @ast::meta_item)
                        -> Option<~[@ast::meta_item]> {
     match meta.node {
-        ast::meta_list(_, ref l) => Some(/* FIXME (#2543) */ copy *l),
+        ast::meta_list(_, ref l) => Some(/* FIXME (#2543) */ (*l).clone()),
         _ => None
     }
 }
@@ -266,7 +266,7 @@ pub fn sort_meta_items(items: &[@ast::meta_item]) -> ~[@ast::meta_item] {
             ast::meta_list(n, ref mis) => {
                 @spanned {
                     node: ast::meta_list(n, sort_meta_items(*mis)),
-                    .. /*bad*/ copy **m
+                    .. /*bad*/ (**m).clone()
                 }
             }
             _ => *m
@@ -286,7 +286,9 @@ pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: &str) ->
 pub fn find_linkage_metas(attrs: &[ast::attribute]) -> ~[@ast::meta_item] {
     do find_attrs_by_name(attrs, "link").flat_map |attr| {
         match attr.node.value.node {
-            ast::meta_list(_, ref items) => /* FIXME (#2543) */ copy *items,
+            ast::meta_list(_, ref items) => {
+                /* FIXME (#2543) */ (*items).clone()
+            }
             _ => ~[]
         }
     }
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index dcd9615ffd0..a9499881cff 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -31,7 +31,7 @@ pub trait Pos {
 }
 
 /// A byte offset
-#[deriving(Eq,IterBytes)]
+#[deriving(Clone, Eq, IterBytes)]
 pub struct BytePos(uint);
 /// A character offset. Because of multibyte utf8 characters, a byte offset
 /// is not equivalent to a character offset. The CodeMap will convert BytePos
@@ -96,15 +96,18 @@ are *absolute* positions from the beginning of the codemap, not positions
 relative to FileMaps. Methods on the CodeMap can be used to relate spans back
 to the original source.
 */
-#[deriving(IterBytes)]
+#[deriving(Clone, IterBytes)]
 pub struct span {
     lo: BytePos,
     hi: BytePos,
     expn_info: Option<@ExpnInfo>
 }
 
-#[deriving(Eq, Encodable, Decodable,IterBytes)]
-pub struct spanned<T> { node: T, span: span }
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
+pub struct spanned<T> {
+    node: T,
+    span: span,
+}
 
 impl cmp::Eq for span {
     fn eq(&self, other: &span) -> bool {
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 2971ad5cc29..717c5571994 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -265,7 +265,7 @@ fn highlight_lines(cm: @codemap::CodeMap,
     // arbitrarily only print up to six lines of the error
     let max_lines = 6u;
     let mut elided = false;
-    let mut display_lines = /* FIXME (#2543) */ copy lines.lines;
+    let mut display_lines = /* FIXME (#2543) */ lines.lines.clone();
     if display_lines.len() > max_lines {
         display_lines = display_lines.slice(0u, max_lines).to_owned();
         elided = true;
@@ -345,11 +345,11 @@ fn print_macro_backtrace(cm: @codemap::CodeMap, sp: span) {
     }
 }
 
-pub fn expect<T:Copy>(diag: @span_handler,
+pub fn expect<T:Clone>(diag: @span_handler,
                        opt: Option<T>,
                        msg: &fn() -> ~str) -> T {
     match opt {
-       Some(ref t) => copy *t,
-       None => diag.handler().bug(msg())
+       Some(ref t) => (*t).clone(),
+       None => diag.handler().bug(msg()),
     }
 }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 0e464208de3..e2f37bd54bd 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -238,7 +238,7 @@ impl ExtCtxt {
 
     pub fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
     pub fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
-    pub fn cfg(&self) -> ast::crate_cfg { copy self.cfg }
+    pub fn cfg(&self) -> ast::crate_cfg { self.cfg.clone() }
     pub fn call_site(&self) -> span {
         match *self.backtrace {
             Some(@ExpnInfo {call_site: cs, _}) => cs,
@@ -249,7 +249,7 @@ impl ExtCtxt {
     pub fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace }
     pub fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); }
     pub fn mod_pop(&self) { self.mod_path.pop(); }
-    pub fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path }
+    pub fn mod_path(&self) -> ~[ast::ident] { (*self.mod_path).clone() }
     pub fn bt_push(&self, ei: codemap::ExpnInfo) {
         match ei {
             ExpnInfo {call_site: cs, callee: ref callee} => {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 89290b78b72..334721a38ed 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -351,7 +351,7 @@ impl AstBuilder for @ExtCtxt {
         };
         Generics {
             ty_params: new_params,
-            .. copy *generics
+            .. (*generics).clone()
         }
     }
 
@@ -611,13 +611,13 @@ impl AstBuilder for @ExtCtxt {
     }
     fn lambda0(&self, _span: span, blk: ast::blk) -> @ast::expr {
         let ext_cx = *self;
-        let blk_e = self.expr(blk.span, ast::expr_block(copy blk));
+        let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
         quote_expr!(|| $blk_e )
     }
 
     fn lambda1(&self, _span: span, blk: ast::blk, ident: ast::ident) -> @ast::expr {
         let ext_cx = *self;
-        let blk_e = self.expr(blk.span, ast::expr_block(copy blk));
+        let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
         quote_expr!(|$ident| $blk_e )
     }
 
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index f90ee1f8d79..a50f4d70f0e 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -335,7 +335,7 @@ impl<'self> TraitDef<'self> {
                     cx.typarambound(p.to_path(cx, span, type_ident, generics))
                 });
             // require the current trait
-            bounds.push(cx.typarambound(copy trait_path));
+            bounds.push(cx.typarambound(trait_path.clone()));
 
             trait_generics.ty_params.push(cx.typaram(ty_param.ident, bounds));
         }
@@ -751,7 +751,7 @@ impl<'self> MethodDef<'self> {
                         do self_vec.iter()
                            .zip(enum_matching_fields.iter())
                            .transform |(&(id, self_f), other)| {
-                        (id, self_f, copy *other)
+                        (id, self_f, (*other).clone())
                     }.collect();
                     substructure = EnumMatching(variant_index, variant, field_tuples);
                 }
@@ -789,7 +789,9 @@ impl<'self> MethodDef<'self> {
                                                                     current_match_str,
                                                                     ast::m_imm);
 
-                matches_so_far.push((index, /*bad*/ copy *variant, idents));
+                matches_so_far.push((index,
+                                     /*bad*/ (*variant).clone(),
+                                     idents));
                 let arm_expr = self.build_enum_match(cx, span,
                                                      enum_def,
                                                      type_ident,
@@ -818,7 +820,9 @@ impl<'self> MethodDef<'self> {
                                                                        current_match_str,
                                                                        ast::m_imm);
 
-                    matches_so_far.push((index, /*bad*/ copy *variant, idents));
+                    matches_so_far.push((index,
+                                         /*bad*/ (*variant).clone(),
+                                         idents));
                     let new_matching =
                         match matching {
                             _ if match_count == 0 => Some(index),
@@ -897,7 +901,8 @@ pub fn create_subpatterns(cx: @ExtCtxt,
                           mutbl: ast::mutability)
                    -> ~[@ast::pat] {
     do field_paths.map |path| {
-        cx.pat(span, ast::pat_ident(ast::bind_by_ref(mutbl), copy *path, None))
+        cx.pat(span,
+               ast::pat_ident(ast::bind_by_ref(mutbl), (*path).clone(), None))
     }
 }
 
@@ -944,7 +949,7 @@ fn create_struct_pattern(cx: @ExtCtxt,
         };
         let path = cx.path_ident(span,
                                  cx.ident_of(fmt!("%s_%u", prefix, i)));
-        paths.push(copy path);
+        paths.push(path.clone());
         ident_expr.push((opt_id, cx.expr_path(path)));
     }
 
@@ -990,7 +995,7 @@ fn create_enum_variant_pattern(cx: @ExtCtxt,
                 let path = cx.path_ident(span,
                                          cx.ident_of(fmt!("%s_%u", prefix, i)));
 
-                paths.push(copy path);
+                paths.push(path.clone());
                 ident_expr.push((None, cx.expr_path(path)));
             }
 
@@ -1029,12 +1034,12 @@ pub fn cs_fold(use_foldl: bool,
         EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
             if use_foldl {
                 do all_fields.iter().fold(base) |old, triple| {
-                    let (_, self_f, other_fs) = copy *triple;
+                    let (_, self_f, other_fs) = (*triple).clone();
                     f(cx, span, old, self_f, other_fs)
                 }
             } else {
                 do all_fields.rev_iter().fold(base) |old, triple| {
-                    let (_, self_f, other_fs) = copy *triple;
+                    let (_, self_f, other_fs) = (*triple).clone();
                     f(cx, span, old, self_f, other_fs)
                 }
             }
@@ -1067,7 +1072,7 @@ pub fn cs_same_method(f: &fn(@ExtCtxt, span, ~[@expr]) -> @expr,
         EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
             // call self_n.method(other_1_n, other_2_n, ...)
             let called = do all_fields.map |triple| {
-                let (_, self_field, other_fields) = copy *triple;
+                let (_, self_field, other_fields) = (*triple).clone();
                 cx.expr_method_call(span,
                                     self_field,
                                     substructure.method_ident,
diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs
index 15fb6ee9ff7..be13e103a72 100644
--- a/src/libsyntax/ext/deriving/iter_bytes.rs
+++ b/src/libsyntax/ext/deriving/iter_bytes.rs
@@ -56,8 +56,9 @@ fn iter_bytes_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @
     let iter_bytes_ident = substr.method_ident;
     let call_iterbytes = |thing_expr| {
         cx.expr_method_call(span,
-                              thing_expr, iter_bytes_ident,
-                              ~[lsb0, borrowed_f])
+                            thing_expr,
+                            iter_bytes_ident,
+                            ~[lsb0, borrowed_f])
     };
     let mut exprs = ~[];
     let fields;
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index cc2050d9bd7..823f21401ca 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -61,7 +61,7 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
     ];
     let rand_call = || {
         cx.expr_call_global(span,
-                            copy rand_ident,
+                            rand_ident.clone(),
                             ~[ rng[0].duplicate(cx) ])
     };
 
@@ -79,7 +79,11 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
             // need to specify the uint-ness of the random number
             let uint_ty = cx.ty_ident(span, cx.ident_of("uint"));
             let r_ty = cx.ty_ident(span, cx.ident_of("R"));
-            let rand_name = cx.path_all(span, true, copy rand_ident, None, ~[ uint_ty, r_ty ]);
+            let rand_name = cx.path_all(span,
+                                        true,
+                                        rand_ident.clone(),
+                                        None,
+                                        ~[ uint_ty, r_ty ]);
             let rand_name = cx.expr_path(rand_name);
 
             // ::std::rand::Rand::rand::<uint>(rng)
diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs
index 471e7212352..5bee804d582 100644
--- a/src/libsyntax/ext/deriving/zero.rs
+++ b/src/libsyntax/ext/deriving/zero.rs
@@ -63,7 +63,7 @@ fn zero_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
         cx.ident_of("zero")
     ];
     let zero_call = || {
-        cx.expr_call_global(span, copy zero_ident, ~[])
+        cx.expr_call_global(span, zero_ident.clone(), ~[])
     };
 
     return match *substr.fields {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 3f7579c7691..ba8e3e72933 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -83,7 +83,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
 
                             //keep going, outside-in
                             let fully_expanded =
-                                copy fld.fold_expr(expanded).node;
+                                fld.fold_expr(expanded).node.clone();
                             cx.bt_pop();
 
                             (fully_expanded, s)
@@ -208,7 +208,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
                     -> Option<@ast::item> {
     let (pth, tts) = match it.node {
         item_mac(codemap::spanned { node: mac_invoc_tt(ref pth, ref tts), _}) => {
-            (pth, copy *tts)
+            (pth, (*tts).clone())
         }
         _ => cx.span_bug(it.span, "invalid item macro invocation")
     };
@@ -298,7 +298,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
         stmt_mac(ref mac, semi) => {
             match mac.node {
                 mac_invoc_tt(ref pth, ref tts) => {
-                    (copy *mac, pth, copy *tts, semi)
+                    ((*mac).clone(), pth, (*tts).clone(), semi)
                 }
             }
         }
@@ -337,7 +337,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
                 Some(stmt) => {
                     let fully_expanded = &stmt.node;
                     cx.bt_pop();
-                    copy *fully_expanded
+                    (*fully_expanded).clone()
                 }
                 None => {
                     cx.span_fatal(pth.span,
@@ -725,7 +725,7 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess,
     // every method/element of AstFoldFns in fold.rs.
     let extsbox = @mut syntax_expander_table();
     let afp = default_ast_fold();
-    let cx = ExtCtxt::new(parse_sess, copy cfg);
+    let cx = ExtCtxt::new(parse_sess, cfg.clone());
     let f_pre = @AstFoldFns {
         fold_expr: |expr,span,recur|
             expand_expr(extsbox, cx, expr, span, recur, afp.fold_expr),
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index a4873e6e34b..eb8b01c427d 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -49,15 +49,15 @@ pub trait append_types {
 impl append_types for ast::Path {
     fn add_ty(&self, ty: ast::Ty) -> ast::Path {
         ast::Path {
-            types: vec::append_one(copy self.types, ty),
-            .. copy *self
+            types: vec::append_one(self.types.clone(), ty),
+            .. (*self).clone()
         }
     }
 
     fn add_tys(&self, tys: ~[ast::Ty]) -> ast::Path {
         ast::Path {
-            types: vec::append(copy self.types, tys),
-            .. copy *self
+            types: vec::append(self.types.clone(), tys),
+            .. (*self).clone()
         }
     }
 }
diff --git a/src/libsyntax/ext/pipes/mod.rs b/src/libsyntax/ext/pipes/mod.rs
index 73c6c6d5fff..b8a0da8fe8f 100644
--- a/src/libsyntax/ext/pipes/mod.rs
+++ b/src/libsyntax/ext/pipes/mod.rs
@@ -67,7 +67,7 @@ pub fn expand_proto(cx: @ExtCtxt, _sp: span, id: ast::ident,
     let cfg = cx.cfg();
     let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic,
                                None,
-                               copy tt);
+                               tt.clone());
     let rdr = tt_rdr as @reader;
     let rust_parser = Parser(sess, cfg, rdr.dup());
 
diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs
index 21bb8266239..e5219721594 100644
--- a/src/libsyntax/ext/pipes/parse_proto.rs
+++ b/src/libsyntax/ext/pipes/parse_proto.rs
@@ -44,7 +44,7 @@ impl proto_parser for parser::Parser {
         let name = interner_get(id.name);
 
         self.expect(&token::COLON);
-        let dir = match copy *self.token {
+        let dir = match (*self.token).clone() {
             token::IDENT(n, _) => interner_get(n.name),
             _ => fail!()
         };
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index e5581cada37..b046c99d144 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -56,7 +56,8 @@ impl gen_send for message {
                 next.generics.ty_params.len());
             let arg_names = vec::from_fn(tys.len(), |i| cx.ident_of("x_"+i.to_str()));
             let args_ast: ~[ast::arg] = arg_names.iter().zip(tys.iter())
-                .transform(|(n, t)| cx.arg(span, copy *n, copy *t)).collect();
+                .transform(|(n, t)|
+                    cx.arg(span, (*n).clone(), (*t).clone())).collect();
 
             let pipe_ty = cx.ty_path(
                 path(~[this.data_name()], span)
@@ -117,7 +118,7 @@ impl gen_send for message {
 
             let mut rty = cx.ty_path(path(~[next.data_name()],
                                           span)
-                                     .add_tys(copy next_state.tys), None);
+                                     .add_tys(next_state.tys.clone()), None);
             if try {
                 rty = cx.ty_option(rty);
             }
@@ -137,7 +138,8 @@ impl gen_send for message {
                 let arg_names = vec::from_fn(tys.len(), |i| "x_" + i.to_str());
 
                 let args_ast: ~[ast::arg] = arg_names.iter().zip(tys.iter())
-                    .transform(|(n, t)| cx.arg(span, cx.ident_of(*n), copy *t)).collect();
+                    .transform(|(n, t)|
+                        cx.arg(span, cx.ident_of(*n), (*t).clone())).collect();
 
                 let args_ast = vec::append(
                     ~[cx.arg(span,
@@ -152,7 +154,7 @@ impl gen_send for message {
                     ~""
                 }
                 else {
-                    ~"(" + arg_names.map(|x| copy *x).connect(", ") + ")"
+                    ~"(" + arg_names.map(|x| (*x).clone()).connect(", ") + ")"
                 };
 
                 let mut body = ~"{ ";
@@ -209,7 +211,7 @@ impl to_type_decls for state {
         let mut items_msg = ~[];
 
         for self.messages.iter().advance |m| {
-            let message(name, span, tys, this, next) = copy *m;
+            let message(name, span, tys, this, next) = (*m).clone();
 
             let tys = match next {
               Some(ref next_state) => {
@@ -225,7 +227,7 @@ impl to_type_decls for state {
                                 cx.ty_path(
                                     path(~[cx.ident_of(dir),
                                            cx.ident_of(next_name)], span)
-                                    .add_tys(copy next_state.tys), None))
+                                    .add_tys(next_state.tys.clone()), None))
               }
               None => tys
             };
@@ -374,7 +376,7 @@ impl gen_init for protocol {
         for self.states.iter().advance |s| {
             for s.generics.ty_params.iter().advance |tp| {
                 match params.iter().find_(|tpp| tp.ident == tpp.ident) {
-                  None => params.push(copy *tp),
+                  None => params.push((*tp).clone()),
                   _ => ()
                 }
             }
@@ -392,7 +394,7 @@ impl gen_init for protocol {
         let fields = do self.states.iter().transform |s| {
             for s.generics.ty_params.iter().advance |tp| {
                 match params.iter().find_(|tpp| tp.ident == tpp.ident) {
-                  None => params.push(copy *tp),
+                  None => params.push((*tp).clone()),
                   _ => ()
                 }
             }
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index 92e1b2bd09f..c93b89daa40 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/src/libsyntax/ext/pipes/proto.rs
@@ -35,12 +35,14 @@ impl direction {
     }
 }
 
+#[deriving(Clone)]
 pub struct next_state {
     state: @str,
     tys: ~[ast::Ty],
 }
 
 // name, span, data, current state, next state
+#[deriving(Clone)]
 pub struct message(@str, span, ~[ast::Ty], state, Option<next_state>);
 
 impl message {
@@ -59,7 +61,7 @@ impl message {
     /// Return the type parameters actually used by this message
     pub fn get_generics(&self) -> ast::Generics {
         match *self {
-          message(_, _, _, this, _) => copy this.generics
+          message(_, _, _, this, _) => this.generics.clone()
         }
     }
 }
@@ -216,7 +218,7 @@ pub fn visit<Tproto, Tstate, Tmessage, V: visitor<Tproto, Tstate, Tmessage>>(
 
     let states: ~[Tstate] = do proto.states.iter().transform |&s| {
         let messages: ~[Tmessage] = do s.messages.iter().transform |m| {
-            let message(name, span, tys, this, next) = copy *m;
+            let message(name, span, tys, this, next) = (*m).clone();
             visitor.visit_message(name, span, tys, this, next)
         }.collect();
         visitor.visit_state(s, messages)
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 3e0e9c93fd0..80e3953da86 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -45,7 +45,7 @@ pub mod rt {
 
     impl ToTokens for ~[token_tree] {
         pub fn to_tokens(&self, _cx: @ExtCtxt) -> ~[token_tree] {
-            copy *self
+            (*self).clone()
         }
     }
 
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index b43536389e2..626a562b92c 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -148,6 +148,6 @@ fn res_rel_file(cx: @ExtCtxt, sp: codemap::span, arg: &Path) -> Path {
         let cu = Path(cx.codemap().span_to_filename(sp));
         cu.dir_path().push_many(arg.components)
     } else {
-        copy *arg
+        (*arg).clone()
     }
 }
diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs
index 5c6032785e3..f7f17d3ba64 100644
--- a/src/libsyntax/ext/trace_macros.rs
+++ b/src/libsyntax/ext/trace_macros.rs
@@ -26,11 +26,7 @@ pub fn expand_trace_macros(cx: @ExtCtxt,
                                None,
                                tt.to_owned());
     let rdr = tt_rdr as @reader;
-    let rust_parser = Parser(
-        sess,
-        copy cfg,
-        rdr.dup()
-    );
+    let rust_parser = Parser(sess, cfg.clone(), rdr.dup());
 
     if rust_parser.is_keyword(keywords::True) {
         cx.set_trace_macros(true);
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index cddba358373..54ccd489171 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -96,6 +96,7 @@ eof: [a $( a )* a b ·]
 /* to avoid costly uniqueness checks, we require that `match_seq` always has a
 nonempty body. */
 
+#[deriving(Clone)]
 pub enum matcher_pos_up { /* to break a circularity */
     matcher_pos_up(Option<~MatcherPos>)
 }
@@ -107,6 +108,7 @@ pub fn is_some(mpu: &matcher_pos_up) -> bool {
     }
 }
 
+#[deriving(Clone)]
 pub struct MatcherPos {
     elts: ~[ast::matcher], // maybe should be <'>? Need to understand regions.
     sep: Option<Token>,
@@ -119,7 +121,7 @@ pub struct MatcherPos {
 
 pub fn copy_up(mpu: &matcher_pos_up) -> ~MatcherPos {
     match *mpu {
-      matcher_pos_up(Some(ref mp)) => copy (*mp),
+      matcher_pos_up(Some(ref mp)) => (*mp).clone(),
       _ => fail!()
     }
 }
@@ -279,7 +281,7 @@ pub fn parse(
 
                         // Only touch the binders we have actually bound
                         for uint::range(ei.match_lo, ei.match_hi) |idx| {
-                            let sub = copy ei.matches[idx];
+                            let sub = ei.matches[idx].clone();
                             new_pos.matches[idx]
                                 .push(@matched_seq(sub,
                                                    mk_sp(ei.sp_lo,
@@ -293,10 +295,10 @@ pub fn parse(
                     // can we go around again?
 
                     // the *_t vars are workarounds for the lack of unary move
-                    match copy ei.sep {
+                    match ei.sep {
                       Some(ref t) if idx == len => { // we need a separator
                         if tok == (*t) { //pass the separator
-                            let mut ei_t = ei;
+                            let mut ei_t = ei.clone();
                             ei_t.idx += 1;
                             next_eis.push(ei_t);
                         }
@@ -311,12 +313,12 @@ pub fn parse(
                     eof_eis.push(ei);
                 }
             } else {
-                match copy ei.elts[idx].node {
+                match ei.elts[idx].node.clone() {
                   /* need to descend into sequence */
                   match_seq(ref matchers, ref sep, zero_ok,
                             match_idx_lo, match_idx_hi) => {
                     if zero_ok {
-                        let mut new_ei = copy ei;
+                        let mut new_ei = ei.clone();
                         new_ei.idx += 1u;
                         //we specifically matched zero repeats.
                         for uint::range(match_idx_lo, match_idx_hi) |idx| {
@@ -329,8 +331,8 @@ pub fn parse(
                     let matches = vec::from_elem(ei.matches.len(), ~[]);
                     let ei_t = ei;
                     cur_eis.push(~MatcherPos {
-                        elts: copy *matchers,
-                        sep: copy *sep,
+                        elts: (*matchers).clone(),
+                        sep: (*sep).clone(),
                         idx: 0u,
                         up: matcher_pos_up(Some(ei_t)),
                         matches: matches,
@@ -340,7 +342,7 @@ pub fn parse(
                   }
                   match_nonterminal(_,_,_) => { bb_eis.push(ei) }
                   match_tok(ref t) => {
-                    let mut ei_t = ei;
+                    let mut ei_t = ei.clone();
                     if (*t) == tok {
                         ei_t.idx += 1;
                         next_eis.push(ei_t);
@@ -388,7 +390,7 @@ pub fn parse(
                 }
                 rdr.next_token();
             } else /* bb_eis.len() == 1 */ {
-                let rust_parser = Parser(sess, copy cfg, rdr.dup());
+                let rust_parser = Parser(sess, cfg.clone(), rdr.dup());
 
                 let mut ei = bb_eis.pop();
                 match ei.elts[ei.idx].node {
@@ -426,7 +428,7 @@ pub fn parse_nt(p: &Parser, name: &str) -> nonterminal {
       "ident" => match *p.token {
         token::IDENT(sn,b) => { p.bump(); token::nt_ident(sn,b) }
         _ => p.fatal(~"expected ident, found "
-                     + token::to_str(get_ident_interner(), &copy *p.token))
+                     + token::to_str(get_ident_interner(), p.token))
       },
       "path" => token::nt_path(p.parse_path_with_tps(false)),
       "tt" => {
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 6b3ce1c9a2f..399a1827c68 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -32,7 +32,10 @@ pub fn add_new_extension(cx: @ExtCtxt,
                       -> base::MacResult {
     // these spans won't matter, anyways
     fn ms(m: matcher_) -> matcher {
-        spanned { node: copy m, span: dummy_sp() }
+        spanned {
+            node: m.clone(),
+            span: dummy_sp()
+        }
     }
 
     let lhs_nm =  gensym_ident("lhs");
@@ -55,7 +58,7 @@ pub fn add_new_extension(cx: @ExtCtxt,
     // Parse the macro_rules! invocation (`none` is for no interpolations):
     let arg_reader = new_tt_reader(cx.parse_sess().span_diagnostic,
                                    None,
-                                   copy arg);
+                                   arg.clone());
     let argument_map = parse_or_else(cx.parse_sess(),
                                      cx.cfg(),
                                      arg_reader as @reader,
@@ -63,12 +66,12 @@ pub fn add_new_extension(cx: @ExtCtxt,
 
     // Extract the arguments:
     let lhses = match *argument_map.get(&lhs_nm) {
-        @matched_seq(ref s, _) => /* FIXME (#2543) */ @copy *s,
+        @matched_seq(ref s, _) => /* FIXME (#2543) */ @(*s).clone(),
         _ => cx.span_bug(sp, "wrong-structured lhs")
     };
 
     let rhses = match *argument_map.get(&rhs_nm) {
-      @matched_seq(ref s, _) => /* FIXME (#2543) */ @copy *s,
+      @matched_seq(ref s, _) => /* FIXME (#2543) */ @(*s).clone(),
       _ => cx.span_bug(sp, "wrong-structured rhs")
     };
 
@@ -132,7 +135,7 @@ pub fn add_new_extension(cx: @ExtCtxt,
                   }
                   failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo {
                     best_fail_spot = sp;
-                    best_fail_msg = copy *msg;
+                    best_fail_msg = (*msg).clone();
                   },
                   error(sp, ref msg) => cx.span_fatal(sp, (*msg))
                 }
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 94ecff178ea..67318c60db9 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -74,10 +74,10 @@ pub fn new_tt_reader(sp_diag: @span_handler,
 
 fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame {
     @mut TtFrame {
-        forest: @mut (copy *f.forest),
+        forest: @mut (*f.forest).clone(),
         idx: f.idx,
         dotdotdoted: f.dotdotdoted,
-        sep: copy f.sep,
+        sep: f.sep.clone(),
         up: match f.up {
             Some(up_frame) => Some(dup_tt_frame(up_frame)),
             None => None
@@ -89,11 +89,11 @@ pub fn dup_tt_reader(r: @mut TtReader) -> @mut TtReader {
     @mut TtReader {
         sp_diag: r.sp_diag,
         stack: dup_tt_frame(r.stack),
-        repeat_idx: copy r.repeat_idx,
-        repeat_len: copy r.repeat_len,
-        cur_tok: copy r.cur_tok,
+        repeat_idx: r.repeat_idx.clone(),
+        repeat_len: r.repeat_len.clone(),
+        cur_tok: r.cur_tok.clone(),
         cur_span: r.cur_span,
-        interpolations: copy r.interpolations,
+        interpolations: r.interpolations.clone(),
     }
 }
 
@@ -122,19 +122,23 @@ fn lookup_cur_matched(r: &mut TtReader, name: ident) -> @named_match {
         }
     }
 }
+
+#[deriving(Clone)]
 enum lis {
-    lis_unconstrained, lis_constraint(uint, ident), lis_contradiction(~str)
+    lis_unconstrained,
+    lis_constraint(uint, ident),
+    lis_contradiction(~str),
 }
 
 fn lockstep_iter_size(t: &token_tree, r: &mut TtReader) -> lis {
     fn lis_merge(lhs: lis, rhs: lis) -> lis {
         match lhs {
-          lis_unconstrained => copy rhs,
-          lis_contradiction(_) => copy lhs,
+          lis_unconstrained => rhs.clone(),
+          lis_contradiction(_) => lhs.clone(),
           lis_constraint(l_len, ref l_id) => match rhs {
-            lis_unconstrained => copy lhs,
-            lis_contradiction(_) => copy rhs,
-            lis_constraint(r_len, _) if l_len == r_len => copy lhs,
+            lis_unconstrained => lhs.clone(),
+            lis_contradiction(_) => rhs.clone(),
+            lis_constraint(r_len, _) if l_len == r_len => lhs.clone(),
             lis_constraint(r_len, ref r_id) => {
                 let l_n = ident_to_str(l_id);
                 let r_n = ident_to_str(r_id);
@@ -163,8 +167,9 @@ fn lockstep_iter_size(t: &token_tree, r: &mut TtReader) -> lis {
 // return the next token from the TtReader.
 // EFFECT: advances the reader's token field
 pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
+    // XXX(pcwalton): Bad copy?
     let ret_val = TokenAndSpan {
-        tok: copy r.cur_tok,
+        tok: r.cur_tok.clone(),
         sp: r.cur_span,
     };
     loop {
@@ -199,7 +204,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
         } else { /* repeat */
             r.stack.idx = 0u;
             r.repeat_idx[r.repeat_idx.len() - 1u] += 1u;
-            match copy r.stack.sep {
+            match r.stack.sep.clone() {
               Some(tk) => {
                 r.cur_tok = tk; /* repeat same span, I guess */
                 return ret_val;
@@ -210,7 +215,8 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
     }
     loop { /* because it's easiest, this handles `tt_delim` not starting
     with a `tt_tok`, even though it won't happen */
-        match copy r.stack.forest[r.stack.idx] {
+        // XXX(pcwalton): Bad copy.
+        match r.stack.forest[r.stack.idx].clone() {
           tt_delim(tts) => {
             r.stack = @mut TtFrame {
                 forest: @mut tts,
@@ -228,7 +234,8 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
             return ret_val;
           }
           tt_seq(sp, tts, sep, zerok) => {
-            let t = tt_seq(sp, copy tts, copy sep, zerok);
+            // XXX(pcwalton): Bad copy.
+            let t = tt_seq(sp, tts.clone(), sep.clone(), zerok);
             match lockstep_iter_size(&t, r) {
               lis_unconstrained => {
                 r.sp_diag.span_fatal(
@@ -278,8 +285,9 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                 return ret_val;
               }
               matched_nonterminal(ref other_whole_nt) => {
+                // XXX(pcwalton): Bad copy.
                 r.cur_span = sp;
-                r.cur_tok = INTERPOLATED(copy *other_whole_nt);
+                r.cur_tok = INTERPOLATED((*other_whole_nt).clone());
                 r.stack.idx += 1u;
                 return ret_val;
               }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 11c29c73a2b..b831bb18643 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -144,17 +144,17 @@ fn fold_tts(tts : &[token_tree], fld: @ast_fold) -> ~[token_tree] {
 }
 
 // apply ident folder if it's an ident, otherwise leave it alone
-fn maybe_fold_ident(t : &token::Token, fld: @ast_fold) -> token::Token {
+fn maybe_fold_ident(t: &token::Token, fld: @ast_fold) -> token::Token {
     match *t {
         token::IDENT(id,followed_by_colons) =>
         token::IDENT(fld.fold_ident(id),followed_by_colons),
-        _ => copy *t
+        _ => (*t).clone()
     }
 }
 
 pub fn fold_fn_decl(decl: &ast::fn_decl, fld: @ast_fold) -> ast::fn_decl {
     ast::fn_decl {
-        inputs: decl.inputs.map(|x| fold_arg_(/*bad*/ copy *x, fld)),
+        inputs: decl.inputs.map(|x| fold_arg_(/*bad*/ (*x).clone(), fld)),
         output: fld.fold_ty(&decl.output),
         cf: decl.cf,
     }
@@ -176,7 +176,7 @@ pub fn fold_ty_param(tp: TyParam,
 
 pub fn fold_ty_params(tps: &OptVec<TyParam>,
                       fld: @ast_fold) -> OptVec<TyParam> {
-    let tps = /*bad*/ copy *tps;
+    let tps = /*bad*/ (*tps).clone();
     tps.map_consume(|tp| fold_ty_param(tp, fld))
 }
 
@@ -209,7 +209,7 @@ pub fn noop_fold_crate(c: &crate_, fld: @ast_fold) -> crate_ {
 }
 
 fn noop_fold_view_item(vi: &view_item_, _fld: @ast_fold) -> view_item_ {
-    return /* FIXME (#2543) */ copy *vi;
+    return /* FIXME (#2543) */ (*vi).clone();
 }
 
 
@@ -226,7 +226,8 @@ fn noop_fold_foreign_item(ni: @foreign_item, fld: @ast_fold)
                 foreign_item_fn(ref fdec, purity, ref generics) => {
                     foreign_item_fn(
                         ast::fn_decl {
-                            inputs: fdec.inputs.map(|a| fold_arg(/*bad*/copy *a)),
+                            inputs: fdec.inputs.map(|a|
+                                fold_arg(/*bad*/(*a).clone())),
                             output: fld.fold_ty(&fdec.output),
                             cf: fdec.cf,
                         },
@@ -299,7 +300,7 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ {
         }
         item_struct(ref struct_def, ref generics) => {
             let struct_def = fold_struct_def(*struct_def, fld);
-            item_struct(struct_def, /* FIXME (#2543) */ copy *generics)
+            item_struct(struct_def, /* FIXME (#2543) */ (*generics).clone())
         }
         item_impl(ref generics, ref ifce, ref ty, ref methods) => {
             item_impl(
@@ -312,7 +313,7 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ {
         item_trait(ref generics, ref traits, ref methods) => {
             let methods = do methods.map |method| {
                 match *method {
-                    required(*) => copy *method,
+                    required(*) => (*method).clone(),
                     provided(method) => provided(fld.fold_method(method))
                 }
             };
@@ -353,7 +354,7 @@ fn fold_struct_field(f: @struct_field, fld: @ast_fold) -> @struct_field {
             kind: f.node.kind,
             id: fld.new_id(f.node.id),
             ty: fld.fold_ty(&f.node.ty),
-            attrs: /* FIXME (#2543) */ copy f.node.attrs,
+            attrs: /* FIXME (#2543) */ f.node.attrs.clone(),
         },
         span: fld.new_span(f.span),
     }
@@ -362,7 +363,7 @@ fn fold_struct_field(f: @struct_field, fld: @ast_fold) -> @struct_field {
 fn noop_fold_method(m: @method, fld: @ast_fold) -> @method {
     @ast::method {
         ident: fld.fold_ident(m.ident),
-        attrs: /* FIXME (#2543) */ copy m.attrs,
+        attrs: /* FIXME (#2543) */ m.attrs.clone(),
         generics: fold_generics(&m.generics, fld),
         explicit_self: m.explicit_self,
         purity: m.purity,
@@ -545,8 +546,10 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ {
         }
         expr_loop_body(f) => expr_loop_body(fld.fold_expr(f)),
         expr_do_body(f) => expr_do_body(fld.fold_expr(f)),
-        expr_lit(_) => copy *e,
-        expr_cast(expr, ref ty) => expr_cast(fld.fold_expr(expr), copy *ty),
+        expr_lit(_) => (*e).clone(),
+        expr_cast(expr, ref ty) => {
+            expr_cast(fld.fold_expr(expr), (*ty).clone())
+        }
         expr_addr_of(m, ohs) => expr_addr_of(m, fld.fold_expr(ohs)),
         expr_if(cond, ref tr, fl) => {
             expr_if(
@@ -623,7 +626,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ {
             expr_inline_asm(inline_asm {
                 inputs: a.inputs.map(|&(c, in)| (c, fld.fold_expr(in))),
                 outputs: a.outputs.map(|&(c, out)| (c, fld.fold_expr(out))),
-                .. copy *a
+                .. (*a).clone()
             })
         }
         expr_mac(ref mac) => expr_mac(fold_mac(mac)),
@@ -662,7 +665,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
         }
     }
     match *t {
-        ty_nil | ty_bot | ty_infer => copy *t,
+        ty_nil | ty_bot | ty_infer => (*t).clone(),
         ty_box(ref mt) => ty_box(fold_mt(mt, fld)),
         ty_uniq(ref mt) => ty_uniq(fold_mt(mt, fld)),
         ty_vec(ref mt) => ty_vec(fold_mt(mt, fld)),
@@ -676,12 +679,12 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
                 onceness: f.onceness,
                 bounds: fold_opt_bounds(&f.bounds, fld),
                 decl: fold_fn_decl(&f.decl, fld),
-                lifetimes: copy f.lifetimes,
+                lifetimes: f.lifetimes.clone(),
             })
         }
         ty_bare_fn(ref f) => {
             ty_bare_fn(@TyBareFn {
-                lifetimes: copy f.lifetimes,
+                lifetimes: f.lifetimes.clone(),
                 purity: f.purity,
                 abis: f.abis,
                 decl: fold_fn_decl(&f.decl, fld)
@@ -727,7 +730,7 @@ fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ {
     match v.kind {
         tuple_variant_kind(ref variant_args) => {
             kind = tuple_variant_kind(do variant_args.map |x| {
-                fold_variant_arg(/*bad*/ copy *x)
+                fold_variant_arg(/*bad*/ (*x).clone())
             })
         }
         struct_variant_kind(struct_def) => {
@@ -844,7 +847,7 @@ impl ast_fold for AstFoldFns {
                 kind: sf.node.kind,
                 id: sf.node.id,
                 ty: self.fold_ty(&sf.node.ty),
-                attrs: copy sf.node.attrs,
+                attrs: sf.node.attrs.clone(),
             },
             span: (self.new_span)(sf.span),
         }
diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs
index ba3b72ec194..6ec80140c76 100644
--- a/src/libsyntax/opt_vec.rs
+++ b/src/libsyntax/opt_vec.rs
@@ -18,7 +18,7 @@
 
 use std::vec::{VecIterator};
 
-#[deriving(Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Encodable, Decodable, IterBytes)]
 pub enum OptVec<T> {
     Empty,
     Vec(~[T])
@@ -113,7 +113,7 @@ pub fn take_vec<T>(v: OptVec<T>) -> ~[T] {
     }
 }
 
-impl<T:Copy> OptVec<T> {
+impl<T:Clone> OptVec<T> {
     fn prepend(&self, t: T) -> OptVec<T> {
         let mut v0 = ~[t];
         match *self {
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index d33b72ae3c9..85c7d5de064 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -39,7 +39,7 @@ impl parser_attr for Parser {
         loop {
             match *self.token {
               token::POUND => {
-                if self.look_ahead(1u) != token::LBRACKET {
+                if self.look_ahead(1, |t| *t != token::LBRACKET) {
                     break;
                 }
                 attrs.push(self.parse_attribute(ast::attr_outer));
@@ -96,7 +96,7 @@ impl parser_attr for Parser {
         loop {
             match *self.token {
               token::POUND => {
-                if self.look_ahead(1u) != token::LBRACKET {
+                if self.look_ahead(1, |t| *t != token::LBRACKET) {
                     // This is an extension
                     break;
                 }
@@ -162,12 +162,10 @@ impl parser_attr for Parser {
 
     // matches meta_seq = ( COMMASEP(meta_item) )
     fn parse_meta_seq(&self) -> ~[@ast::meta_item] {
-        copy self.parse_seq(
-            &token::LPAREN,
-            &token::RPAREN,
-            seq_sep_trailing_disallowed(token::COMMA),
-            |p| p.parse_meta_item()
-        ).node
+        self.parse_seq(&token::LPAREN,
+                       &token::RPAREN,
+                       seq_sep_trailing_disallowed(token::COMMA),
+                       |p| p.parse_meta_item()).node
     }
 
     fn parse_optional_meta(&self) -> ~[@ast::meta_item] {
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 01af33b13b8..83af5bade3a 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -22,7 +22,7 @@ use std::io;
 use std::str;
 use std::uint;
 
-#[deriving(Eq)]
+#[deriving(Clone, Eq)]
 pub enum cmnt_style {
     isolated, // No code on either side of each line of the comment
     trailing, // Code exists to the left of the comment
@@ -30,6 +30,7 @@ pub enum cmnt_style {
     blank_line, // Just a manual blank line "\n\n", for layout
 }
 
+#[deriving(Clone)]
 pub struct cmnt {
     style: cmnt_style,
     lines: ~[~str],
@@ -324,6 +325,7 @@ fn consume_comment(rdr: @mut StringReader,
     debug!("<<< consume comment");
 }
 
+#[deriving(Clone)]
 pub struct lit {
     lit: ~str,
     pos: BytePos
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 22e0a150a19..8db80cddded 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -20,6 +20,7 @@ use parse::token::{str_to_ident};
 use std::char;
 use std::either;
 use std::u64;
+use std::util;
 
 pub use ext::tt::transcribe::{TtReader, new_tt_reader};
 
@@ -93,7 +94,7 @@ fn dup_string_reader(r: @mut StringReader) -> @mut StringReader {
         col: r.col,
         curr: r.curr,
         filemap: r.filemap,
-        peek_tok: copy r.peek_tok,
+        peek_tok: r.peek_tok.clone(),
         peek_span: r.peek_span
     }
 }
@@ -103,7 +104,7 @@ impl reader for StringReader {
     // return the next token. EFFECT: advances the string_reader.
     fn next_token(@mut self) -> TokenAndSpan {
         let ret_val = TokenAndSpan {
-            tok: /*bad*/copy self.peek_tok,
+            tok: util::replace(&mut self.peek_tok, token::UNDERSCORE),
             sp: self.peek_span,
         };
         string_advance_token(self);
@@ -114,8 +115,9 @@ impl reader for StringReader {
     }
     fn span_diag(@mut self) -> @span_handler { self.span_diagnostic }
     fn peek(@mut self) -> TokenAndSpan {
+        // XXX(pcwalton): Bad copy!
         TokenAndSpan {
-            tok: /*bad*/copy self.peek_tok,
+            tok: self.peek_tok.clone(),
             sp: self.peek_span,
         }
     }
@@ -131,7 +133,7 @@ impl reader for TtReader {
     fn span_diag(@mut self) -> @span_handler { self.sp_diag }
     fn peek(@mut self) -> TokenAndSpan {
         TokenAndSpan {
-            tok: copy self.cur_tok,
+            tok: self.cur_tok.clone(),
             sp: self.cur_span,
         }
     }
@@ -143,8 +145,8 @@ impl reader for TtReader {
 fn string_advance_token(r: @mut StringReader) {
     match (consume_whitespace_and_comments(r)) {
         Some(comment) => {
-            r.peek_tok = copy comment.tok;
             r.peek_span = comment.sp;
+            r.peek_tok = comment.tok;
         },
         None => {
             if is_eof(r) {
@@ -818,7 +820,7 @@ mod test {
             sp:span {lo:BytePos(21),hi:BytePos(23),expn_info: None}};
         assert_eq!(tok1,tok2);
         // the 'main' id is already read:
-        assert_eq!(copy string_reader.last_pos,BytePos(28));
+        assert_eq!(string_reader.last_pos.clone(), BytePos(28));
         // read another token:
         let tok3 = string_reader.next_token();
         let tok4 = TokenAndSpan{
@@ -826,7 +828,7 @@ mod test {
             sp:span {lo:BytePos(24),hi:BytePos(28),expn_info: None}};
         assert_eq!(tok3,tok4);
         // the lparen is already read:
-        assert_eq!(copy string_reader.last_pos,BytePos(29))
+        assert_eq!(string_reader.last_pos.clone(), BytePos(29))
     }
 
     // check that the given reader produces the desired stream
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 84cc49192ed..410849b4482 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -79,7 +79,7 @@ pub fn parse_crate_from_file(
     cfg: ast::crate_cfg,
     sess: @mut ParseSess
 ) -> @ast::crate {
-    new_parser_from_file(sess, /*bad*/ copy cfg, input).parse_crate_mod()
+    new_parser_from_file(sess, /*bad*/ cfg.clone(), input).parse_crate_mod()
     // why is there no p.abort_if_errors here?
 }
 
@@ -89,12 +89,10 @@ pub fn parse_crate_from_source_str(
     cfg: ast::crate_cfg,
     sess: @mut ParseSess
 ) -> @ast::crate {
-    let p = new_parser_from_source_str(
-        sess,
-        /*bad*/ copy cfg,
-        name,
-        source
-    );
+    let p = new_parser_from_source_str(sess,
+                                       /*bad*/ cfg.clone(),
+                                       name,
+                                       source);
     maybe_aborted(p.parse_crate_mod(),p)
 }
 
@@ -457,7 +455,7 @@ mod test {
     }
 
     fn parser_done(p: Parser){
-        assert_eq!(copy *p.token,token::EOF);
+        assert_eq!((*p.token).clone(), token::EOF);
     }
 
     #[test] fn parse_ident_pat () {
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 01ed6531273..148fca36ed2 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -314,8 +314,8 @@ impl ParserObsoleteMethods for Parser {
 
     pub fn try_parse_obsolete_with(&self) -> bool {
         if *self.token == token::COMMA
-            && self.token_is_obsolete_ident("with",
-                                            &self.look_ahead(1u)) {
+            && self.look_ahead(1,
+                               |t| self.token_is_obsolete_ident("with", t)) {
             self.bump();
         }
         if self.eat_obsolete_ident("with") {
@@ -329,8 +329,8 @@ impl ParserObsoleteMethods for Parser {
 
     pub fn try_parse_obsolete_priv_section(&self, attrs: &[attribute])
                                            -> bool {
-        if self.is_keyword(keywords::Priv) && self.look_ahead(1) ==
-                token::LBRACE {
+        if self.is_keyword(keywords::Priv) &&
+                self.look_ahead(1, |t| *t == token::LBRACE) {
             self.obsolete(*self.span, ObsoletePrivSection);
             self.eat_keyword(keywords::Priv);
             self.bump();
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 497000a6cbf..c67b2aefb63 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -97,6 +97,7 @@ use opt_vec::OptVec;
 use std::either::Either;
 use std::either;
 use std::hashmap::HashSet;
+use std::util;
 use std::vec;
 
 #[deriving(Eq)]
@@ -111,8 +112,9 @@ type arg_or_capture_item = Either<arg, ()>;
 type item_info = (ident, item_, Option<~[attribute]>);
 
 pub enum item_or_view_item {
-    // indicates a failure to parse any kind of item:
-    iovi_none,
+    // Indicates a failure to parse any kind of item. The attributes are
+    // returned.
+    iovi_none(~[attribute]),
     iovi_item(@item),
     iovi_foreign_item(@foreign_item),
     iovi_view_item(view_item)
@@ -141,7 +143,7 @@ macro_rules! maybe_whole_expr (
                     Some($p.mk_expr(
                         ($p).span.lo,
                         ($p).span.hi,
-                        expr_path(/* bad */ copy *pt)))
+                        expr_path(/* bad */ (*pt).clone())))
                 }
                 _ => None
             };
@@ -158,48 +160,83 @@ macro_rules! maybe_whole_expr (
 
 macro_rules! maybe_whole (
     ($p:expr, $constructor:ident) => (
-        match copy *($p).token {
-            INTERPOLATED(token::$constructor(x)) => {
-                $p.bump();
-                return x;
+        {
+            let __found__ = match *($p).token {
+                INTERPOLATED(token::$constructor(_)) => {
+                    Some(($p).bump_and_get())
+                }
+                _ => None
+            };
+            match __found__ {
+                Some(INTERPOLATED(token::$constructor(x))) => {
+                    return x.clone()
+                }
+                _ => {}
             }
-            _ => ()
-       }
+        }
     );
     (deref $p:expr, $constructor:ident) => (
-        match copy *($p).token {
-            INTERPOLATED(token::$constructor(x)) => {
-                $p.bump();
-                return copy *x;
+        {
+            let __found__ = match *($p).token {
+                INTERPOLATED(token::$constructor(_)) => {
+                    Some(($p).bump_and_get())
+                }
+                _ => None
+            };
+            match __found__ {
+                Some(INTERPOLATED(token::$constructor(x))) => {
+                    return (*x).clone()
+                }
+                _ => {}
             }
-            _ => ()
         }
     );
     (Some $p:expr, $constructor:ident) => (
-        match copy *($p).token {
-            INTERPOLATED(token::$constructor(x)) => {
-                $p.bump();
-                return Some(x);
+        {
+            let __found__ = match *($p).token {
+                INTERPOLATED(token::$constructor(_)) => {
+                    Some(($p).bump_and_get())
+                }
+                _ => None
+            };
+            match __found__ {
+                Some(INTERPOLATED(token::$constructor(x))) => {
+                    return Some(x.clone()),
+                }
+                _ => {}
             }
-            _ => ()
         }
     );
     (iovi $p:expr, $constructor:ident) => (
-        match copy *($p).token {
-            INTERPOLATED(token::$constructor(x)) => {
-                $p.bump();
-                return iovi_item(x);
+        {
+            let __found__ = match *($p).token {
+                INTERPOLATED(token::$constructor(_)) => {
+                    Some(($p).bump_and_get())
+                }
+                _ => None
+            };
+            match __found__ {
+                Some(INTERPOLATED(token::$constructor(x))) => {
+                    return iovi_item(x.clone())
+                }
+                _ => {}
             }
-            _ => ()
         }
     );
     (pair_empty $p:expr, $constructor:ident) => (
-        match copy *($p).token {
-            INTERPOLATED(token::$constructor(x)) => {
-                $p.bump();
-                return (~[], x);
+        {
+            let __found__ = match *($p).token {
+                INTERPOLATED(token::$constructor(_)) => {
+                    Some(($p).bump_and_get())
+                }
+                _ => None
+            };
+            match __found__ {
+                Some(INTERPOLATED(token::$constructor(x))) => {
+                    return (~[], x.clone())
+                }
+                _ => {}
             }
-            _ => ()
         }
     )
 )
@@ -227,18 +264,23 @@ pub fn Parser(sess: @mut ParseSess,
               cfg: ast::crate_cfg,
               rdr: @reader)
            -> Parser {
-    let tok0 = copy rdr.next_token();
+    let tok0 = rdr.next_token();
     let interner = get_ident_interner();
+    let span = tok0.sp;
+    let placeholder = TokenAndSpan {
+        tok: token::UNDERSCORE,
+        sp: span,
+    };
 
     Parser {
         reader: rdr,
         interner: interner,
         sess: sess,
         cfg: cfg,
-        token: @mut copy tok0.tok,
-        span: @mut tok0.sp,
-        last_span: @mut tok0.sp,
-        buffer: @mut ([copy tok0, .. 4]),
+        token: @mut tok0.tok,
+        span: @mut span,
+        last_span: @mut span,
+        buffer: @mut ([placeholder, .. 4]),
         buffer_start: @mut 0,
         buffer_end: @mut 0,
         tokens_consumed: @mut 0,
@@ -534,14 +576,29 @@ impl Parser {
         let next = if *self.buffer_start == *self.buffer_end {
             self.reader.next_token()
         } else {
-            let next = copy self.buffer[*self.buffer_start];
-            *self.buffer_start = (*self.buffer_start + 1) & 3;
-            next
+            // Avoid token copies with `util::replace`.
+            let buffer_start = *self.buffer_start as uint;
+            let next_index = (buffer_start + 1) & 3 as uint;
+            *self.buffer_start = next_index as int;
+
+            let placeholder = TokenAndSpan {
+                tok: token::UNDERSCORE,
+                sp: *self.span,
+            };
+            util::replace(&mut self.buffer[buffer_start], placeholder)
         };
-        *self.token = /*bad*/copy next.tok;
         *self.span = next.sp;
+        *self.token = next.tok;
         *self.tokens_consumed += 1u;
     }
+
+    // Advance the parser by one token and return the bumped token.
+    pub fn bump_and_get(&self) -> token::Token {
+        let old_token = util::replace(self.token, token::UNDERSCORE);
+        self.bump();
+        old_token
+    }
+
     // EFFECT: replace the current token and span with the given one
     pub fn replace_token(&self,
                          next: token::Token,
@@ -556,13 +613,14 @@ impl Parser {
         }
         return (4 - *self.buffer_start) + *self.buffer_end;
     }
-    pub fn look_ahead(&self, distance: uint) -> token::Token {
+    pub fn look_ahead<R>(&self, distance: uint, f: &fn(&token::Token) -> R)
+                         -> R {
         let dist = distance as int;
         while self.buffer_length() < dist {
             self.buffer[*self.buffer_end] = self.reader.next_token();
             *self.buffer_end = (*self.buffer_end + 1) & 3;
         }
-        return copy self.buffer[(*self.buffer_start + dist - 1) & 3].tok;
+        f(&self.buffer[(*self.buffer_start + dist - 1) & 3].tok)
     }
     pub fn fatal(&self, m: &str) -> ! {
         self.sess.span_diagnostic.span_fatal(*self.span, m)
@@ -902,11 +960,13 @@ impl Parser {
                         one_tuple = true;
                     }
                 }
-                let t = if ts.len() == 1 && !one_tuple {
-                    copy ts[0].node
-                } else {
-                    ty_tup(ts)
-                };
+
+                if ts.len() == 1 && !one_tuple {
+                    self.expect(&token::RPAREN);
+                    return ts[0]
+                }
+
+                let t = ty_tup(ts);
                 self.expect(&token::RPAREN);
                 t
             }
@@ -958,7 +1018,7 @@ impl Parser {
         } else if self.eat_keyword(keywords::Extern) {
             // EXTERN FUNCTION
             self.parse_ty_bare_fn()
-        } else if self.token_is_closure_keyword(&copy *self.token) {
+        } else if self.token_is_closure_keyword(self.token) {
             // CLOSURE
             let result = self.parse_ty_closure(ast::BorrowedSigil, None);
             self.obsolete(*self.last_span, ObsoleteBareFnType);
@@ -990,13 +1050,13 @@ impl Parser {
             }
 
             token::IDENT(*) => {
-                if self.look_ahead(1u) == token::BINOP(token::SLASH) &&
-                    self.token_is_closure_keyword(&self.look_ahead(2u))
-                {
+                if self.look_ahead(1, |t| *t == token::BINOP(token::SLASH)) &&
+                        self.look_ahead(2, |t|
+                                        self.token_is_closure_keyword(t)) {
                     let lifetime = self.parse_lifetime();
                     self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
                     return self.parse_ty_closure(sigil, Some(lifetime));
-                } else if self.token_is_closure_keyword(&copy *self.token) {
+                } else if self.token_is_closure_keyword(self.token) {
                     return self.parse_ty_closure(sigil, None);
                 }
             }
@@ -1023,7 +1083,7 @@ impl Parser {
         // look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
         let opt_lifetime = self.parse_opt_lifetime();
 
-        if self.token_is_closure_keyword(&copy *self.token) {
+        if self.token_is_closure_keyword(self.token) {
             return self.parse_ty_closure(BorrowedSigil, opt_lifetime);
         }
 
@@ -1056,7 +1116,7 @@ impl Parser {
         } else if *self.token == token::ANDAND {
             1
         } else if *self.token == token::BINOP(token::PLUS) {
-            if self.look_ahead(1) == token::BINOP(token::PLUS) {
+            if self.look_ahead(1, |t| *t == token::BINOP(token::PLUS)) {
                 2
             } else {
                 1
@@ -1064,10 +1124,10 @@ impl Parser {
         } else { 0 };
         if offset == 0 {
             is_plain_ident(&*self.token)
-                && self.look_ahead(1) == token::COLON
+                && self.look_ahead(1, |t| *t == token::COLON)
         } else {
-            is_plain_ident(&self.look_ahead(offset))
-                && self.look_ahead(offset + 1) == token::COLON
+            self.look_ahead(offset, |t| is_plain_ident(t))
+                && self.look_ahead(offset + 1, |t| *t == token::COLON)
         }
     }
 
@@ -1133,7 +1193,7 @@ impl Parser {
             self.obsolete(*self.last_span, ObsoleteFixedLengthVectorType);
             Some(self.parse_expr())
         } else if *self.token == token::COMMA &&
-                self.look_ahead(1) == token::DOTDOT {
+                self.look_ahead(1, |t| *t == token::DOTDOT) {
             self.bump();
             self.bump();
             Some(self.parse_expr())
@@ -1165,10 +1225,9 @@ impl Parser {
         } else if self.eat_keyword(keywords::False) {
             lit_bool(false)
         } else {
-            // XXX: This is a really bad copy!
-            let tok = copy *self.token;
-            self.bump();
-            self.lit_from_token(&tok)
+            let token = self.bump_and_get();
+            let lit = self.lit_from_token(&token);
+            lit
         };
         codemap::spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
     }
@@ -1209,12 +1268,17 @@ impl Parser {
         loop {
             match *self.token {
                 token::MOD_SEP => {
-                    match self.look_ahead(1) {
-                        token::IDENT(*) => {
-                            self.bump();
-                            ids.push(self.parse_ident());
+                    let is_ident = do self.look_ahead(1) |t| {
+                        match *t {
+                            token::IDENT(*) => true,
+                            _ => false,
                         }
-                        _ => break
+                    };
+                    if is_ident {
+                        self.bump();
+                        ids.push(self.parse_ident());
+                    } else {
+                        break
                     }
                 }
                 _ => break
@@ -1253,7 +1317,7 @@ impl Parser {
         // be written "foo/&x"
         let rp_slash = {
             if *self.token == token::BINOP(token::SLASH)
-                && self.look_ahead(1u) == token::BINOP(token::AND)
+                && self.look_ahead(1, |t| *t == token::BINOP(token::AND))
             {
                 self.bump(); self.bump();
                 self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
@@ -1294,10 +1358,12 @@ impl Parser {
             }
         };
 
-        ast::Path { span: mk_sp(lo, hi),
-                     rp: rp,
-                     types: tps,
-                     .. path }
+        ast::Path {
+            span: mk_sp(lo, hi),
+            rp: rp,
+            types: tps,
+            .. path.clone()
+        }
     }
 
     // parse a path optionally with type parameters. If 'colons'
@@ -1328,7 +1394,7 @@ impl Parser {
 
             // Also accept the (obsolete) syntax `foo/`
             token::IDENT(*) => {
-                if self.look_ahead(1u) == token::BINOP(token::SLASH) {
+                if self.look_ahead(1, |t| *t == token::BINOP(token::SLASH)) {
                     self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
                     Some(self.parse_lifetime())
                 } else {
@@ -1589,7 +1655,7 @@ impl Parser {
                 // Nonempty vector.
                 let first_expr = self.parse_expr();
                 if *self.token == token::COMMA &&
-                        self.look_ahead(1) == token::DOTDOT {
+                        self.look_ahead(1, |t| *t == token::DOTDOT) {
                     // Repeating vector syntax: [ 0, ..512 ]
                     self.bump();
                     self.bump();
@@ -1658,12 +1724,11 @@ impl Parser {
                 };
 
                 let ket = token::flip_delimiter(&*self.token);
-                let tts = self.parse_unspanned_seq(
-                    &copy *self.token,
-                    &ket,
-                    seq_sep_none(),
-                    |p| p.parse_token_tree()
-                );
+                self.bump();
+
+                let tts = self.parse_seq_to_end(&ket,
+                                                seq_sep_none(),
+                                                |p| p.parse_token_tree());
                 let hi = self.span.hi;
 
                 return self.mk_mac_expr(lo, hi, mac_invoc_tt(pth, tts));
@@ -1809,8 +1874,7 @@ impl Parser {
             self.bump();
             (None, zerok)
         } else {
-            let sep = copy *self.token;
-            self.bump();
+            let sep = self.bump_and_get();
             if *self.token == token::BINOP(token::STAR)
                 || *self.token == token::BINOP(token::PLUS) {
                 let zerok = *self.token == token::BINOP(token::STAR);
@@ -1877,9 +1941,7 @@ impl Parser {
 
         // turn the next token into a tt_tok:
         fn parse_any_tt_tok(p: &Parser) -> token_tree{
-            let res = tt_tok(*p.span, copy *p.token);
-            p.bump();
-            res
+            tt_tok(*p.span, p.bump_and_get())
         }
 
         match *self.token {
@@ -1925,32 +1987,25 @@ impl Parser {
         let name_idx = @mut 0u;
         match *self.token {
             token::LBRACE | token::LPAREN | token::LBRACKET => {
-                self.parse_matcher_subseq(
-                    name_idx,
-                    copy *self.token,
-                    // tjc: not sure why we need a copy
-                    token::flip_delimiter(self.token)
-                )
+                let other_delimiter = token::flip_delimiter(self.token);
+                self.bump();
+                self.parse_matcher_subseq_upto(name_idx, &other_delimiter)
             }
             _ => self.fatal("expected open delimiter")
         }
     }
 
-
     // This goofy function is necessary to correctly match parens in matchers.
     // Otherwise, `$( ( )` would be a valid matcher, and `$( () )` would be
     // invalid. It's similar to common::parse_seq.
-    pub fn parse_matcher_subseq(&self,
-                                name_idx: @mut uint,
-                                bra: token::Token,
-                                ket: token::Token)
-                                -> ~[matcher] {
+    pub fn parse_matcher_subseq_upto(&self,
+                                     name_idx: @mut uint,
+                                     ket: &token::Token)
+                                     -> ~[matcher] {
         let mut ret_val = ~[];
         let mut lparens = 0u;
 
-        self.expect(&bra);
-
-        while *self.token != ket || lparens > 0u {
+        while *self.token != *ket || lparens > 0u {
             if *self.token == token::LPAREN { lparens += 1u; }
             if *self.token == token::RPAREN { lparens -= 1u; }
             ret_val.push(self.parse_matcher(name_idx));
@@ -1968,11 +2023,9 @@ impl Parser {
             self.bump();
             if *self.token == token::LPAREN {
                 let name_idx_lo = *name_idx;
-                let ms = self.parse_matcher_subseq(
-                    name_idx,
-                    token::LPAREN,
-                    token::RPAREN
-                );
+                self.bump();
+                let ms = self.parse_matcher_subseq_upto(name_idx,
+                                                        &token::RPAREN);
                 if ms.len() == 0u {
                     self.fatal("repetition body must be nonempty");
                 }
@@ -1987,9 +2040,7 @@ impl Parser {
                 m
             }
         } else {
-            let m = match_tok(copy *self.token);
-            self.bump();
-            m
+            match_tok(self.bump_and_get())
         };
 
         return spanned(lo, self.span.hi, m);
@@ -2094,16 +2145,15 @@ impl Parser {
     // parse an expression of binops of at least min_prec precedence
     pub fn parse_more_binops(&self, lhs: @expr, min_prec: uint) -> @expr {
         if self.expr_is_complete(lhs) { return lhs; }
-        let peeked = copy *self.token;
-        if peeked == token::BINOP(token::OR) &&
+        if token::BINOP(token::OR) == *self.token &&
             (*self.restriction == RESTRICT_NO_BAR_OP ||
              *self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) {
             lhs
-        } else if peeked == token::OROR &&
+        } else if token::OROR == *self.token &&
             *self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP {
             lhs
         } else {
-            let cur_opt = token_to_binop(peeked);
+            let cur_opt = token_to_binop(self.token);
             match cur_opt {
                 Some(cur_op) => {
                     let cur_prec = operator_prec(cur_op);
@@ -2290,23 +2340,31 @@ impl Parser {
                 let block = self.parse_lambda_block_expr();
                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
                                             ctor(block));
-                let args = vec::append(copy *args, [last_arg]);
+                let args = vec::append((*args).clone(), [last_arg]);
                 self.mk_expr(lo, block.span.hi, expr_call(f, args, sugar))
             }
             expr_method_call(_, f, i, ref tps, ref args, NoSugar) => {
                 let block = self.parse_lambda_block_expr();
                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
                                             ctor(block));
-                let args = vec::append(copy *args, [last_arg]);
+                let args = vec::append((*args).clone(), [last_arg]);
                 self.mk_expr(lo, block.span.hi,
-                             self.mk_method_call(f, i, copy *tps, args, sugar))
+                             self.mk_method_call(f,
+                                                 i,
+                                                 (*tps).clone(),
+                                                 args,
+                                                 sugar))
             }
             expr_field(f, i, ref tps) => {
                 let block = self.parse_lambda_block_expr();
                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
                                             ctor(block));
                 self.mk_expr(lo, block.span.hi,
-                             self.mk_method_call(f, i, copy *tps, ~[last_arg], sugar))
+                             self.mk_method_call(f,
+                                                 i,
+                                                 (*tps).clone(),
+                                                 ~[last_arg],
+                                                 sugar))
             }
             expr_path(*) | expr_call(*) | expr_method_call(*) |
                 expr_paren(*) => {
@@ -2343,7 +2401,7 @@ impl Parser {
         let is_loop_header =
             *self.token == token::LBRACE
             || (is_ident(&*self.token)
-                && self.look_ahead(1) == token::LBRACE);
+                && self.look_ahead(1, |t| *t == token::LBRACE));
 
         if is_loop_header {
             // This is a loop body
@@ -2373,11 +2431,10 @@ impl Parser {
 
     // For distingishing between record literals and blocks
     fn looking_at_record_literal(&self) -> bool {
-        let lookahead = self.look_ahead(1);
         *self.token == token::LBRACE &&
-            (token::is_keyword(keywords::Mut, &lookahead) ||
-             (is_plain_ident(&lookahead) &&
-              self.look_ahead(2) == token::COLON))
+            (self.look_ahead(1, |t| token::is_keyword(keywords::Mut, t)) ||
+             (self.look_ahead(1, |t| token::is_plain_ident(t)) &&
+              self.look_ahead(2, |t| *t == token::COLON)))
     }
 
     fn parse_match_expr(&self) -> @expr {
@@ -2388,7 +2445,9 @@ impl Parser {
         while *self.token != token::RBRACE {
             let pats = self.parse_pats();
             let mut guard = None;
-            if self.eat_keyword(keywords::If) { guard = Some(self.parse_expr()); }
+            if self.eat_keyword(keywords::If) {
+                guard = Some(self.parse_expr());
+            }
             self.expect(&token::FAT_ARROW);
             let expr = self.parse_expr_res(RESTRICT_STMT_EXPR);
 
@@ -2554,12 +2613,21 @@ impl Parser {
         maybe_whole!(self, nt_pat);
 
         let lo = self.span.lo;
-        let mut hi = self.span.hi;
+        let mut hi;
         let pat;
-        match /*bad*/ copy *self.token {
+        match *self.token {
             // parse _
-          token::UNDERSCORE => { self.bump(); pat = pat_wild; }
-            // parse @pat
+          token::UNDERSCORE => {
+            self.bump();
+            pat = pat_wild;
+            hi = self.last_span.hi;
+            return @ast::pat {
+                id: self.get_id(),
+                node: pat,
+                span: mk_sp(lo, hi)
+            }
+          }
+          // parse @pat
           token::AT => {
             self.bump();
             let sub = self.parse_pat();
@@ -2580,6 +2648,12 @@ impl Parser {
               }
               _ => pat_box(sub)
             };
+            hi = self.last_span.hi;
+            return @ast::pat {
+                id: self.get_id(),
+                node: pat,
+                span: mk_sp(lo, hi)
+            }
           }
           token::TILDE => {
             // parse ~pat
@@ -2602,6 +2676,12 @@ impl Parser {
               }
               _ => pat_uniq(sub)
             };
+            hi = self.last_span.hi;
+            return @ast::pat {
+                id: self.get_id(),
+                node: pat,
+                span: mk_sp(lo, hi)
+            }
           }
           token::BINOP(token::AND) => {
               // parse &pat
@@ -2623,7 +2703,13 @@ impl Parser {
                       pat_lit(vst)
                   }
               _ => pat_region(sub)
-              };
+            };
+            hi = self.last_span.hi;
+            return @ast::pat {
+                id: self.get_id(),
+                node: pat,
+                span: mk_sp(lo, hi)
+            }
           }
           token::LBRACE => {
             self.bump();
@@ -2632,6 +2718,12 @@ impl Parser {
             self.bump();
             self.obsolete(*self.span, ObsoleteRecordPattern);
             pat = pat_wild;
+            hi = self.last_span.hi;
+            return @ast::pat {
+                id: self.get_id(),
+                node: pat,
+                span: mk_sp(lo, hi)
+            }
           }
           token::LPAREN => {
             // parse (pat,pat,pat,...) as tuple
@@ -2646,7 +2738,7 @@ impl Parser {
                 pat = pat_lit(expr);
             } else {
                 let mut fields = ~[self.parse_pat()];
-                if self.look_ahead(1) != token::RPAREN {
+                if self.look_ahead(1, |t| *t != token::RPAREN) {
                     while *self.token == token::COMMA {
                         self.bump();
                         fields.push(self.parse_pat());
@@ -2657,6 +2749,12 @@ impl Parser {
                 self.expect(&token::RPAREN);
                 pat = pat_tup(fields);
             }
+            hi = self.last_span.hi;
+            return @ast::pat {
+                id: self.get_id(),
+                node: pat,
+                span: mk_sp(lo, hi)
+            }
           }
           token::LBRACKET => {
             // parse [pat,pat,...] as vector pattern
@@ -2666,118 +2764,130 @@ impl Parser {
             hi = self.span.hi;
             self.expect(&token::RBRACKET);
             pat = ast::pat_vec(before, slice, after);
+            hi = self.last_span.hi;
+            return @ast::pat {
+                id: self.get_id(),
+                node: pat,
+                span: mk_sp(lo, hi)
+            }
           }
-          ref tok => {
-            if !is_ident_or_path(tok)
+          _ => {}
+        }
+
+        let tok = self.token;
+        if !is_ident_or_path(tok)
                 || self.is_keyword(keywords::True)
-                || self.is_keyword(keywords::False)
-            {
-                // Parse an expression pattern or exp .. exp.
-                //
-                // These expressions are limited to literals (possibly
-                // preceded by unary-minus) or identifiers.
-                let val = self.parse_literal_maybe_minus();
-                if self.eat(&token::DOTDOT) {
-                    let end = if is_ident_or_path(tok) {
-                        let path = self.parse_path_with_tps(true);
-                        let hi = self.span.hi;
-                        self.mk_expr(lo, hi, expr_path(path))
-                    } else {
-                        self.parse_literal_maybe_minus()
-                    };
-                    pat = pat_range(val, end);
+                || self.is_keyword(keywords::False) {
+            // Parse an expression pattern or exp .. exp.
+            //
+            // These expressions are limited to literals (possibly
+            // preceded by unary-minus) or identifiers.
+            let val = self.parse_literal_maybe_minus();
+            if self.eat(&token::DOTDOT) {
+                let end = if is_ident_or_path(tok) {
+                    let path = self.parse_path_with_tps(true);
+                    let hi = self.span.hi;
+                    self.mk_expr(lo, hi, expr_path(path))
                 } else {
-                    pat = pat_lit(val);
-                }
-            } else if self.eat_keyword(keywords::Ref) {
-                // parse ref pat
-                let mutbl = self.parse_mutability();
-                pat = self.parse_pat_ident(bind_by_ref(mutbl));
-            } else if self.eat_keyword(keywords::Copy) {
-                // parse copy pat
-                self.obsolete(*self.span, ObsoletePatternCopyKeyword);
-                pat = self.parse_pat_ident(bind_infer);
+                    self.parse_literal_maybe_minus()
+                };
+                pat = pat_range(val, end);
             } else {
-                let can_be_enum_or_struct;
-                match self.look_ahead(1) {
+                pat = pat_lit(val);
+            }
+        } else if self.eat_keyword(keywords::Ref) {
+            // parse ref pat
+            let mutbl = self.parse_mutability();
+            pat = self.parse_pat_ident(bind_by_ref(mutbl));
+        } else if self.eat_keyword(keywords::Copy) {
+            // parse copy pat
+            self.obsolete(*self.span, ObsoletePatternCopyKeyword);
+            pat = self.parse_pat_ident(bind_infer);
+        } else {
+            let can_be_enum_or_struct = do self.look_ahead(1) |t| {
+                match *t {
                     token::LPAREN | token::LBRACKET | token::LT |
-                    token::LBRACE | token::MOD_SEP =>
-                        can_be_enum_or_struct = true,
-                    _ =>
-                        can_be_enum_or_struct = false
+                    token::LBRACE | token::MOD_SEP => true,
+                    _ => false,
                 }
+            };
 
-                if self.look_ahead(1) == token::DOTDOT {
-                    let start = self.parse_expr_res(RESTRICT_NO_BAR_OP);
-                    self.eat(&token::DOTDOT);
-                    let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
-                    pat = pat_range(start, end);
+            if self.look_ahead(1, |t| *t == token::DOTDOT) {
+                let start = self.parse_expr_res(RESTRICT_NO_BAR_OP);
+                self.eat(&token::DOTDOT);
+                let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
+                pat = pat_range(start, end);
+            } else if is_plain_ident(&*self.token) && !can_be_enum_or_struct {
+                let name = self.parse_path_without_tps();
+                let sub;
+                if self.eat(&token::AT) {
+                    // parse foo @ pat
+                    sub = Some(self.parse_pat());
+                } else {
+                    // or just foo
+                    sub = None;
                 }
-                else if is_plain_ident(&*self.token) && !can_be_enum_or_struct {
-                    let name = self.parse_path_without_tps();
-                    let sub;
-                    if self.eat(&token::AT) {
-                        // parse foo @ pat
-                        sub = Some(self.parse_pat());
-                    } else {
-                        // or just foo
-                        sub = None;
+                pat = pat_ident(bind_infer, name, sub);
+            } else {
+                // parse an enum pat
+                let enum_path = self.parse_path_with_tps(true);
+                match *self.token {
+                    token::LBRACE => {
+                        self.bump();
+                        let (fields, etc) =
+                            self.parse_pat_fields();
+                        self.bump();
+                        pat = pat_struct(enum_path, fields, etc);
                     }
-                    pat = pat_ident(bind_infer, name, sub);
-                } else {
-                    // parse an enum pat
-                    let enum_path = self.parse_path_with_tps(true);
-                    match *self.token {
-                        token::LBRACE => {
-                            self.bump();
-                            let (fields, etc) =
-                                self.parse_pat_fields();
-                            self.bump();
-                            pat = pat_struct(enum_path, fields, etc);
-                        }
-                        _ => {
-                            let mut args: ~[@pat] = ~[];
-                            match *self.token {
-                              token::LPAREN => match self.look_ahead(1u) {
-                                token::BINOP(token::STAR) => {
-                                    // This is a "top constructor only" pat
-                                      self.bump(); self.bump();
-                                      self.expect(&token::RPAREN);
-                                      pat = pat_enum(enum_path, None);
-                                  }
-                                _ => {
-                                    args = self.parse_unspanned_seq(
-                                        &token::LPAREN,
-                                        &token::RPAREN,
-                                        seq_sep_trailing_disallowed(
-                                            token::COMMA
-                                        ),
-                                        |p| p.parse_pat()
-                                    );
-                                    pat = pat_enum(enum_path, Some(args));
-                                  }
-                              },
-                              _ => {
-                                  if enum_path.idents.len()==1u {
-                                      // it could still be either an enum
-                                      // or an identifier pattern, resolve
-                                      // will sort it out:
-                                      pat = pat_ident(bind_infer,
-                                                      enum_path,
-                                                      None);
-                                  } else {
-                                      pat = pat_enum(enum_path, Some(args));
-                                  }
-                              }
+                    _ => {
+                        let mut args: ~[@pat] = ~[];
+                        match *self.token {
+                          token::LPAREN => {
+                            let is_star = do self.look_ahead(1) |t| {
+                                match *t {
+                                    token::BINOP(token::STAR) => true,
+                                    _ => false,
+                                }
+                            };
+                            if is_star {
+                                // This is a "top constructor only" pat
+                                self.bump();
+                                self.bump();
+                                self.expect(&token::RPAREN);
+                                pat = pat_enum(enum_path, None);
+                            } else {
+                                args = self.parse_unspanned_seq(
+                                    &token::LPAREN,
+                                    &token::RPAREN,
+                                    seq_sep_trailing_disallowed(token::COMMA),
+                                    |p| p.parse_pat()
+                                );
+                                pat = pat_enum(enum_path, Some(args));
                             }
+                          },
+                          _ => {
+                              if enum_path.idents.len()==1u {
+                                  // it could still be either an enum
+                                  // or an identifier pattern, resolve
+                                  // will sort it out:
+                                  pat = pat_ident(bind_infer,
+                                                  enum_path,
+                                                  None);
+                              } else {
+                                  pat = pat_enum(enum_path, Some(args));
+                              }
+                          }
                         }
                     }
                 }
             }
-            hi = self.last_span.hi;
-          }
         }
-        @ast::pat { id: self.get_id(), node: pat, span: mk_sp(lo, hi) }
+        hi = self.last_span.hi;
+        @ast::pat {
+            id: self.get_id(),
+            node: pat,
+            span: mk_sp(lo, hi),
+        }
     }
 
     // parse ident or ident @ pat
@@ -2878,23 +2988,22 @@ impl Parser {
     pub fn parse_stmt(&self, item_attrs: ~[attribute]) -> @stmt {
         maybe_whole!(self, nt_stmt);
 
-        fn check_expected_item(p: &Parser, current_attrs: &[attribute]) {
+        fn check_expected_item(p: &Parser, found_attrs: bool) {
             // If we have attributes then we should have an item
-            if !current_attrs.is_empty() {
-                p.span_err(*p.last_span,
-                           "expected item after attributes");
+            if found_attrs {
+                p.span_err(*p.last_span, "expected item after attributes");
             }
         }
 
         let lo = self.span.lo;
         if self.is_keyword(keywords::Let) {
-            check_expected_item(self, item_attrs);
+            check_expected_item(self, !item_attrs.is_empty());
             self.expect_keyword(keywords::Let);
             let decl = self.parse_let();
             return @spanned(lo, decl.span.hi, stmt_decl(decl, self.get_id()));
         } else if is_ident(&*self.token)
             && !token::is_any_keyword(self.token)
-            && self.look_ahead(1) == token::NOT {
+            && self.look_ahead(1, |t| *t == token::NOT) {
             // parse a macro invocation. Looks like there's serious
             // overlap here; if this clause doesn't catch it (and it
             // won't, for brace-delimited macros) it will fall through
@@ -2908,7 +3017,7 @@ impl Parser {
             // somewhat awkward... and probably undocumented. Of course,
             // I could just be wrong.
 
-            check_expected_item(self, item_attrs);
+            check_expected_item(self, !item_attrs.is_empty());
 
             // Potential trouble: if we allow macros with paths instead of
             // idents, we'd need to look ahead past the whole path here...
@@ -2944,8 +3053,8 @@ impl Parser {
             }
 
         } else {
-            match self.parse_item_or_view_item(/*bad*/ copy item_attrs,
-                                                           false) {
+            let found_attrs = !item_attrs.is_empty();
+            match self.parse_item_or_view_item(item_attrs, false) {
                 iovi_item(i) => {
                     let hi = i.span.hi;
                     let decl = @spanned(lo, hi, decl_item(i));
@@ -2958,10 +3067,10 @@ impl Parser {
                 iovi_foreign_item(_) => {
                     self.fatal("foreign items are not allowed here");
                 }
-                iovi_none() => { /* fallthrough */ }
+                iovi_none(_) => { /* fallthrough */ }
             }
 
-            check_expected_item(self, item_attrs);
+            check_expected_item(self, found_attrs);
 
             // Remainder are line-expr stmts.
             let e = self.parse_expr_res(RESTRICT_STMT_EXPR);
@@ -3056,48 +3165,66 @@ impl Parser {
                     match stmt.node {
                         stmt_expr(e, stmt_id) => {
                             // expression without semicolon
-                            match copy *self.token {
+                            let has_semi;
+                            match *self.token {
                                 token::SEMI => {
-                                    self.bump();
-                                    stmts.push(@codemap::spanned {
-                                        node: stmt_semi(e, stmt_id),
-                                        .. copy *stmt});
+                                    has_semi = true;
                                 }
                                 token::RBRACE => {
+                                    has_semi = false;
                                     expr = Some(e);
                                 }
-                                t => {
+                                ref t => {
+                                    has_semi = false;
                                     if classify::stmt_ends_with_semi(stmt) {
                                         self.fatal(
                                             fmt!(
                                                 "expected `;` or `}` after \
                                                  expression but found `%s`",
-                                                self.token_to_str(&t)
+                                                self.token_to_str(t)
                                             )
                                         );
                                     }
                                     stmts.push(stmt);
                                 }
                             }
+
+                            if has_semi {
+                                self.bump();
+                                stmts.push(@codemap::spanned {
+                                    node: stmt_semi(e, stmt_id),
+                                    span: stmt.span,
+                                });
+                            }
                         }
                         stmt_mac(ref m, _) => {
                             // statement macro; might be an expr
+                            let has_semi;
                             match *self.token {
                                 token::SEMI => {
-                                    self.bump();
-                                    stmts.push(@codemap::spanned {
-                                        node: stmt_mac(copy *m, true),
-                                        .. copy *stmt});
+                                    has_semi = true;
                                 }
                                 token::RBRACE => {
                                     // if a block ends in `m!(arg)` without
                                     // a `;`, it must be an expr
+                                    has_semi = false;
                                     expr = Some(
                                         self.mk_mac_expr(stmt.span.lo,
                                                          stmt.span.hi,
-                                                         copy m.node));
+                                                         m.node.clone()));
+                                }
+                                _ => {
+                                    has_semi = false;
+                                    stmts.push(stmt);
                                 }
-                                _ => { stmts.push(stmt); }
+                            }
+
+                            if has_semi {
+                                self.bump();
+                                stmts.push(@codemap::spanned {
+                                    node: stmt_mac((*m).clone(), true),
+                                    span: stmt.span,
+                                });
                             }
                         }
                         _ => { // all other kinds of statements:
@@ -3302,10 +3429,10 @@ impl Parser {
             p: &Parser
         ) -> ast::explicit_self_ {
             // We need to make sure it isn't a mode or a type
-            if token::is_keyword(keywords::Self, &p.look_ahead(1)) ||
-                ((token::is_keyword(keywords::Const, &p.look_ahead(1)) ||
-                  token::is_keyword(keywords::Mut, &p.look_ahead(1))) &&
-                 token::is_keyword(keywords::Self, &p.look_ahead(2))) {
+            if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) ||
+                ((p.look_ahead(1, |t| token::is_keyword(keywords::Const, t)) ||
+                  p.look_ahead(1, |t| token::is_keyword(keywords::Mut, t))) &&
+                 p.look_ahead(2, |t| token::is_keyword(keywords::Self, t))) {
 
                 p.bump();
                 let mutability = p.parse_mutability();
@@ -3326,25 +3453,30 @@ impl Parser {
             //
             // We already know that the current token is `&`.
 
-            if (token::is_keyword(keywords::Self, &this.look_ahead(1))) {
+            if this.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
                 this.bump();
                 this.expect_self_ident();
                 sty_region(None, m_imm)
-            } else if (this.token_is_mutability(&this.look_ahead(1)) &&
-                       token::is_keyword(keywords::Self, &this.look_ahead(2))) {
+            } else if this.look_ahead(1, |t| this.token_is_mutability(t)) &&
+                    this.look_ahead(2,
+                                    |t| token::is_keyword(keywords::Self,
+                                                          t)) {
                 this.bump();
                 let mutability = this.parse_mutability();
                 this.expect_self_ident();
                 sty_region(None, mutability)
-            } else if (this.token_is_lifetime(&this.look_ahead(1)) &&
-                       token::is_keyword(keywords::Self, &this.look_ahead(2))) {
+            } else if this.look_ahead(1, |t| this.token_is_lifetime(t)) &&
+                       this.look_ahead(2,
+                                       |t| token::is_keyword(keywords::Self,
+                                                             t)) {
                 this.bump();
                 let lifetime = this.parse_lifetime();
                 this.expect_self_ident();
                 sty_region(Some(lifetime), m_imm)
-            } else if (this.token_is_lifetime(&this.look_ahead(1)) &&
-                       this.token_is_mutability(&this.look_ahead(2)) &&
-                       token::is_keyword(keywords::Self, &this.look_ahead(3))) {
+            } else if this.look_ahead(1, |t| this.token_is_lifetime(t)) &&
+                      this.look_ahead(2, |t| this.token_is_mutability(t)) &&
+                      this.look_ahead(3, |t| token::is_keyword(keywords::Self,
+                                                               t)) {
                 this.bump();
                 let lifetime = this.parse_lifetime();
                 let mutability = this.parse_mutability();
@@ -3563,7 +3695,7 @@ impl Parser {
             let opt_trait_ref = match ty.node {
                 ty_path(ref path, None, node_id) => {
                     Some(trait_ref {
-                        path: /* bad */ copy *path,
+                        path: /* bad */ (*path).clone(),
                         ref_id: node_id
                     })
                 }
@@ -3768,8 +3900,10 @@ impl Parser {
 
     // given a termination token and a vector of already-parsed
     // attributes (of length 0 or 1), parse all of the items in a module
-    fn parse_mod_items(&self, term: token::Token,
-                       first_item_attrs: ~[attribute]) -> _mod {
+    fn parse_mod_items(&self,
+                       term: token::Token,
+                       first_item_attrs: ~[attribute])
+                       -> _mod {
         // parse all of the items up to closing or an attribute.
         // view items are legal here.
         let ParsedItemsAndViewItems {
@@ -3777,8 +3911,7 @@ impl Parser {
             view_items: view_items,
             items: starting_items,
             _
-        } = self.parse_items_and_view_items(first_item_attrs,
-                                            true, true);
+        } = self.parse_items_and_view_items(first_item_attrs, true, true);
         let mut items: ~[@item] = starting_items;
         let attrs_remaining_len = attrs_remaining.len();
 
@@ -3793,25 +3926,19 @@ impl Parser {
             }
             debug!("parse_mod_items: parse_item_or_view_item(attrs=%?)",
                    attrs);
-            match self.parse_item_or_view_item(
-                /*bad*/ copy attrs,
-                true // macros allowed
-            ) {
+            match self.parse_item_or_view_item(attrs,
+                                               true /* macros allowed */) {
               iovi_item(item) => items.push(item),
               iovi_view_item(view_item) => {
-                self.span_fatal(view_item.span, "view items must be  declared at the top of the \
-                                                 module");
+                self.span_fatal(view_item.span,
+                                "view items must be declared at the top of \
+                                 the module");
               }
               _ => {
-                self.fatal(
-                    fmt!(
-                        "expected item but found `%s`",
-                        self.this_token_to_str()
-                    )
-                );
+                self.fatal(fmt!("expected item but found `%s`",
+                                self.this_token_to_str()));
               }
             }
-            debug!("parse_mod_items: attrs=%?", attrs);
         }
 
         if first && attrs_remaining_len > 0u {
@@ -3834,7 +3961,7 @@ impl Parser {
     }
 
     // parse a `mod <foo> { ... }` or `mod <foo>;` item
-    fn parse_item_mod(&self, outer_attrs: ~[ast::attribute]) -> item_info {
+    fn parse_item_mod(&self, outer_attrs: &[ast::attribute]) -> item_info {
         let id_span = *self.span;
         let id = self.parse_ident();
         if *self.token == token::SEMI {
@@ -3853,7 +3980,7 @@ impl Parser {
         }
     }
 
-    fn push_mod_path(&self, id: ident, attrs: ~[ast::attribute]) {
+    fn push_mod_path(&self, id: ident, attrs: &[ast::attribute]) {
         let default_path = token::interner_get(id.name);
         let file_path = match ::attr::first_attr_value_str_by_name(
             attrs, "path") {
@@ -3869,17 +3996,18 @@ impl Parser {
     }
 
     // read a module from a source file.
-    fn eval_src_mod(&self, id: ast::ident,
-                    outer_attrs: ~[ast::attribute],
-                    id_sp: span) -> (ast::item_, ~[ast::attribute]) {
-
+    fn eval_src_mod(&self,
+                    id: ast::ident,
+                    outer_attrs: &[ast::attribute],
+                    id_sp: span)
+                    -> (ast::item_, ~[ast::attribute]) {
         let prefix = Path(self.sess.cm.span_to_filename(*self.span));
         let prefix = prefix.dir_path();
         let mod_path_stack = &*self.mod_path_stack;
         let mod_path = Path(".").push_many(*mod_path_stack);
         let default_path = token::interner_get(id.name).to_owned() + ".rs";
         let file_path = match ::attr::first_attr_value_str_by_name(
-            outer_attrs, "path") {
+                outer_attrs, "path") {
             Some(d) => {
                 let path = Path(d);
                 if !path.is_absolute {
@@ -3891,14 +4019,17 @@ impl Parser {
             None => mod_path.push(default_path)
         };
 
-        self.eval_src_mod_from_path(prefix, file_path,
-                                    outer_attrs, id_sp)
+        self.eval_src_mod_from_path(prefix,
+                                    file_path,
+                                    outer_attrs.to_owned(),
+                                    id_sp)
     }
 
-    fn eval_src_mod_from_path(&self, prefix: Path, path: Path,
+    fn eval_src_mod_from_path(&self,
+                              prefix: Path,
+                              path: Path,
                               outer_attrs: ~[ast::attribute],
-                              id_sp: span
-                             ) -> (ast::item_, ~[ast::attribute]) {
+                              id_sp: span) -> (ast::item_, ~[ast::attribute]) {
 
         let full_path = if path.is_absolute {
             path
@@ -3924,8 +4055,10 @@ impl Parser {
         self.sess.included_mod_stack.push(full_path.clone());
 
         let p0 =
-            new_sub_parser_from_file(self.sess, copy self.cfg,
-                                     &full_path, id_sp);
+            new_sub_parser_from_file(self.sess,
+                                     self.cfg.clone(),
+                                     &full_path,
+                                     id_sp);
         let (inner, next) = p0.parse_inner_attrs_and_next();
         let mod_attrs = vec::append(outer_attrs, inner);
         let first_item_outer_attrs = next;
@@ -4074,7 +4207,7 @@ impl Parser {
 
             return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
                                           item_foreign_mod(m), visibility,
-                                          maybe_append(/*bad*/ copy attrs,
+                                          maybe_append(attrs,
                                                        Some(inner))));
         }
 
@@ -4087,7 +4220,7 @@ impl Parser {
         self.expect(&token::SEMI);
         iovi_view_item(ast::view_item {
             node: view_item_extern_mod(ident, metadata, self.get_id()),
-            attrs: copy attrs,
+            attrs: attrs,
             vis: visibility,
             span: mk_sp(lo, self.last_span.hi)
         })
@@ -4253,8 +4386,8 @@ impl Parser {
         }
     }
 
-    fn fn_expr_lookahead(&self, tok: token::Token) -> bool {
-        match tok {
+    fn fn_expr_lookahead(&self, tok: &token::Token) -> bool {
+        match *tok {
           token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true,
           _ => false
         }
@@ -4304,11 +4437,10 @@ impl Parser {
     // flags; on failure, return iovi_none.
     // NB: this function no longer parses the items inside an
     // extern mod.
-    fn parse_item_or_view_item(
-        &self,
-        attrs: ~[attribute],
-        macros_allowed: bool
-    ) -> item_or_view_item {
+    fn parse_item_or_view_item(&self,
+                               attrs: ~[attribute],
+                               macros_allowed: bool)
+                               -> item_or_view_item {
         maybe_whole!(iovi self, nt_item);
         let lo = self.span.lo;
 
@@ -4348,7 +4480,7 @@ impl Parser {
         // the rest are all guaranteed to be items:
         if (self.is_keyword(keywords::Const) ||
             (self.is_keyword(keywords::Static) &&
-             !token::is_keyword(keywords::Fn, &self.look_ahead(1)))) {
+             self.look_ahead(1, |t| !token::is_keyword(keywords::Fn, t)))) {
             // CONST / STATIC ITEM
             if self.is_keyword(keywords::Const) {
                 self.obsolete(*self.span, ObsoleteConstItem);
@@ -4360,7 +4492,7 @@ impl Parser {
                                           maybe_append(attrs, extra_attrs)));
         }
         if self.is_keyword(keywords::Fn) &&
-            !self.fn_expr_lookahead(self.look_ahead(1u)) {
+                self.look_ahead(1, |f| !self.fn_expr_lookahead(f)) {
             // FUNCTION ITEM
             self.bump();
             let (ident, item_, extra_attrs) =
@@ -4380,7 +4512,7 @@ impl Parser {
                                           maybe_append(attrs, extra_attrs)));
         }
         if self.is_keyword(keywords::Unsafe)
-            && self.look_ahead(1u) != token::LBRACE {
+            && self.look_ahead(1u, |t| *t != token::LBRACE) {
             // UNSAFE FUNCTION ITEM
             self.bump();
             self.expect_keyword(keywords::Fn);
@@ -4392,8 +4524,7 @@ impl Parser {
         }
         if self.eat_keyword(keywords::Mod) {
             // MODULE ITEM
-            let (ident, item_, extra_attrs) =
-                self.parse_item_mod(/*bad*/ copy attrs);
+            let (ident, item_, extra_attrs) = self.parse_item_mod(attrs);
             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
                                           visibility,
                                           maybe_append(attrs, extra_attrs)));
@@ -4438,11 +4569,10 @@ impl Parser {
     }
 
     // parse a foreign item; on failure, return iovi_none.
-    fn parse_foreign_item(
-        &self,
-        attrs: ~[attribute],
-        macros_allowed: bool
-    ) -> item_or_view_item {
+    fn parse_foreign_item(&self,
+                          attrs: ~[attribute],
+                          macros_allowed: bool)
+                          -> item_or_view_item {
         maybe_whole!(iovi self, nt_item);
         let lo = self.span.lo;
 
@@ -4471,10 +4601,10 @@ impl Parser {
         visibility : visibility
     ) -> item_or_view_item {
         if macros_allowed && !token::is_any_keyword(self.token)
-                && self.look_ahead(1) == token::NOT
-                && (is_plain_ident(&self.look_ahead(2))
-                    || self.look_ahead(2) == token::LPAREN
-                    || self.look_ahead(2) == token::LBRACE) {
+                && self.look_ahead(1, |t| *t == token::NOT)
+                && (self.look_ahead(2, |t| is_plain_ident(t))
+                    || self.look_ahead(2, |t| *t == token::LPAREN)
+                    || self.look_ahead(2, |t| *t == token::LBRACE)) {
             // MACRO INVOCATION ITEM
             if attrs.len() > 0 {
                 self.fatal("attrs on macros are not yet supported");
@@ -4496,12 +4626,10 @@ impl Parser {
             let tts = match *self.token {
                 token::LPAREN | token::LBRACE => {
                     let ket = token::flip_delimiter(&*self.token);
-                    self.parse_unspanned_seq(
-                        &copy *self.token,
-                        &ket,
-                        seq_sep_none(),
-                        |p| p.parse_token_tree()
-                    )
+                    self.bump();
+                    self.parse_seq_to_end(&ket,
+                                          seq_sep_none(),
+                                          |p| p.parse_token_tree())
                 }
                 _ => self.fatal("expected open delimiter")
             };
@@ -4526,12 +4654,12 @@ impl Parser {
             s.push_char('`');
             self.span_fatal(*self.last_span, s);
         }
-        return iovi_none;
+        return iovi_none(attrs);
     }
 
     pub fn parse_item(&self, attrs: ~[attribute]) -> Option<@ast::item> {
         match self.parse_item_or_view_item(attrs, true) {
-            iovi_none =>
+            iovi_none(attrs) =>
                 None,
             iovi_view_item(_) =>
                 self.fatal("view items are not allowed here"),
@@ -4648,18 +4776,19 @@ impl Parser {
     }
 
     fn is_view_item(&self) -> bool {
-        let tok;
-        let next_tok;
         if !self.is_keyword(keywords::Pub) && !self.is_keyword(keywords::Priv) {
-            tok = copy *self.token;
-            next_tok = self.look_ahead(1);
+            token::is_keyword(keywords::Use, self.token)
+                || (token::is_keyword(keywords::Extern, self.token) &&
+                    self.look_ahead(1,
+                                    |t| token::is_keyword(keywords::Mod, t)))
         } else {
-            tok = self.look_ahead(1);
-            next_tok = self.look_ahead(2);
-        };
-        token::is_keyword(keywords::Use, &tok)
-            || (token::is_keyword(keywords::Extern, &tok) &&
-                token::is_keyword(keywords::Mod, &next_tok))
+            self.look_ahead(1, |t| token::is_keyword(keywords::Use, t))
+                || (self.look_ahead(1,
+                                    |t| token::is_keyword(keywords::Extern,
+                                                          t)) &&
+                    self.look_ahead(2,
+                                    |t| token::is_keyword(keywords::Mod, t)))
+        }
     }
 
     // parse a view item.
@@ -4706,11 +4835,14 @@ impl Parser {
         // view items, and regular items) ... except that because
         // of macros, I'd like to delay that entire check until later.
         loop {
-            match self.parse_item_or_view_item(/*bad*/ copy attrs,
-                                                           macros_allowed) {
-                iovi_none => {
-                    done = true;
-                    break;
+            match self.parse_item_or_view_item(attrs, macros_allowed) {
+                iovi_none(attrs) => {
+                    return ParsedItemsAndViewItems {
+                        attrs_remaining: attrs,
+                        view_items: view_items,
+                        items: items,
+                        foreign_items: ~[]
+                    }
                 }
                 iovi_view_item(view_item) => {
                     match view_item.node {
@@ -4740,23 +4872,24 @@ impl Parser {
         }
 
         // Next, parse items.
-        if !done {
-            loop {
-                match self.parse_item_or_view_item(/*bad*/ copy attrs,
-                                                   macros_allowed) {
-                    iovi_none => break,
-                    iovi_view_item(view_item) => {
-                        self.span_err(view_item.span,
-                                      "`use` and `extern mod` declarations must precede items");
-                    }
-                    iovi_item(item) => {
-                        items.push(item)
-                    }
-                    iovi_foreign_item(_) => {
-                        fail!();
-                    }
+        loop {
+            match self.parse_item_or_view_item(attrs, macros_allowed) {
+                iovi_none(returned_attrs) => {
+                    attrs = returned_attrs;
+                    break
+                }
+                iovi_view_item(view_item) => {
+                    attrs = self.parse_outer_attributes();
+                    self.span_err(view_item.span,
+                                  "`use` and `extern mod` declarations must precede items");
+                }
+                iovi_item(item) => {
+                    attrs = self.parse_outer_attributes();
+                    items.push(item)
+                }
+                iovi_foreign_item(_) => {
+                    fail!();
                 }
-                attrs = self.parse_outer_attributes();
             }
         }
 
@@ -4777,9 +4910,10 @@ impl Parser {
                                     self.parse_outer_attributes());
         let mut foreign_items = ~[];
         loop {
-            match self.parse_foreign_item(/*bad*/ copy attrs, macros_allowed) {
-                iovi_none => {
+            match self.parse_foreign_item(attrs, macros_allowed) {
+                iovi_none(returned_attrs) => {
                     if *self.token == token::RBRACE {
+                        attrs = returned_attrs;
                         break
                     }
                     self.unexpected();
@@ -4821,7 +4955,7 @@ impl Parser {
         @spanned(lo, self.span.lo,
                  ast::crate_ { module: m,
                                attrs: inner,
-                               config: copy self.cfg })
+                               config: self.cfg.clone() })
     }
 
     pub fn parse_str(&self) -> @str {
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 01860c3ae99..8e14e56439e 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -20,7 +20,7 @@ use std::local_data;
 use std::rand;
 use std::rand::RngUtil;
 
-#[deriving(Encodable, Decodable, Eq, IterBytes)]
+#[deriving(Clone, Encodable, Decodable, Eq, IterBytes)]
 pub enum binop {
     PLUS,
     MINUS,
@@ -34,7 +34,7 @@ pub enum binop {
     SHR,
 }
 
-#[deriving(Encodable, Decodable, Eq, IterBytes)]
+#[deriving(Clone, Encodable, Decodable, Eq, IterBytes)]
 pub enum Token {
     /* Expression-operator symbols. */
     EQ,
@@ -95,7 +95,7 @@ pub enum Token {
     EOF,
 }
 
-#[deriving(Encodable, Decodable, Eq, IterBytes)]
+#[deriving(Clone, Encodable, Decodable, Eq, IterBytes)]
 /// For interpolation during macro expansion.
 pub enum nonterminal {
     nt_item(@ast::item),
@@ -350,8 +350,8 @@ pub mod special_idents {
  * Maps a token to a record specifying the corresponding binary
  * operator
  */
-pub fn token_to_binop(tok: Token) -> Option<ast::binop> {
-  match tok {
+pub fn token_to_binop(tok: &Token) -> Option<ast::binop> {
+  match *tok {
       BINOP(STAR)    => Some(ast::mul),
       BINOP(SLASH)   => Some(ast::div),
       BINOP(PERCENT) => Some(ast::rem),
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 8889fe91cc5..af2a4977082 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -64,19 +64,25 @@
 use std::io;
 use std::vec;
 
-#[deriving(Eq)]
-pub enum breaks { consistent, inconsistent, }
+#[deriving(Clone, Eq)]
+pub enum breaks {
+    consistent,
+    inconsistent,
+}
 
+#[deriving(Clone)]
 pub struct break_t {
     offset: int,
     blank_space: int
 }
 
+#[deriving(Clone)]
 pub struct begin_t {
     offset: int,
     breaks: breaks
 }
 
+#[deriving(Clone)]
 pub enum token {
     STRING(@str, int),
     BREAK(break_t),
@@ -476,11 +482,11 @@ impl Printer {
     pub fn print(&mut self, x: token, L: int) {
         debug!("print %s %d (remaining line space=%d)", tok_str(x), L,
                self.space);
-        debug!("%s", buf_str(copy self.token,
-                           copy self.size,
-                           self.left,
-                           self.right,
-                           6u));
+        debug!("%s", buf_str(self.token.clone(),
+                             self.size.clone(),
+                             self.left,
+                             self.right,
+                             6));
         match x {
           BEGIN(b) => {
             if L > self.space {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 5b4a6d15a12..2f0241967d9 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -121,11 +121,15 @@ pub fn print_crate(cm: @CodeMap,
         s: pp::mk_printer(out, default_columns),
         cm: Some(cm),
         intr: intr,
-        comments: Some(copy cmnts),
+        comments: Some(cmnts),
         // If the code is post expansion, don't use the table of
         // literals, since it doesn't correspond with the literals
         // in the AST anymore.
-        literals: if is_expanded { None } else { Some(copy lits) },
+        literals: if is_expanded {
+            None
+        } else {
+            Some(lits)
+        },
         cur_cmnt_and_lit: @mut CurrentCommentAndLiteral {
             cur_cmnt: 0,
             cur_lit: 0
@@ -405,15 +409,19 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
         pclose(s);
       }
       ast::ty_bare_fn(f) => {
-          let generics = ast::Generics {lifetimes: copy f.lifetimes,
-                                        ty_params: opt_vec::Empty};
+          let generics = ast::Generics {
+            lifetimes: f.lifetimes.clone(),
+            ty_params: opt_vec::Empty
+          };
           print_ty_fn(s, Some(f.abis), None, &None,
                       f.purity, ast::Many, &f.decl, None, &None,
                       Some(&generics), None);
       }
       ast::ty_closure(f) => {
-          let generics = ast::Generics {lifetimes: copy f.lifetimes,
-                                        ty_params: opt_vec::Empty};
+          let generics = ast::Generics {
+            lifetimes: f.lifetimes.clone(),
+            ty_params: opt_vec::Empty
+          };
           print_ty_fn(s, None, Some(f.sigil), &f.region,
                       f.purity, f.onceness, &f.decl, None, &f.bounds,
                       Some(&generics), None);
@@ -1167,13 +1175,13 @@ pub fn print_expr(s: @ps, expr: &ast::expr) {
         pclose(s);
       }
       ast::expr_call(func, ref args, sugar) => {
-        let mut base_args = copy *args;
+        let mut base_args = (*args).clone();
         let blk = print_call_pre(s, sugar, &mut base_args);
         print_expr(s, func);
         print_call_post(s, sugar, &blk, &mut base_args);
       }
       ast::expr_method_call(_, func, ident, ref tys, ref args, sugar) => {
-        let mut base_args = copy *args;
+        let mut base_args = (*args).clone();
         let blk = print_call_pre(s, sugar, &mut base_args);
         print_expr(s, func);
         word(s.s, ".");
@@ -1798,12 +1806,10 @@ pub fn print_meta_item(s: @ps, item: &ast::meta_item) {
       ast::meta_list(name, ref items) => {
         word(s.s, name);
         popen(s);
-        commasep(
-            s,
-            consistent,
-            items.as_slice(),
-            |p, &i| print_meta_item(p, i)
-        );
+        commasep(s,
+                 consistent,
+                 items.as_slice(),
+                 |p, &i| print_meta_item(p, i));
         pclose(s);
       }
     }
@@ -2061,7 +2067,7 @@ pub fn next_lit(s: @ps, pos: BytePos) -> Option<comments::lit> {
     match s.literals {
       Some(ref lits) => {
         while s.cur_cmnt_and_lit.cur_lit < lits.len() {
-            let ltrl = /*bad*/ copy (*lits)[s.cur_cmnt_and_lit.cur_lit];
+            let ltrl = (*lits)[s.cur_cmnt_and_lit.cur_lit].clone();
             if ltrl.pos > pos { return None; }
             s.cur_cmnt_and_lit.cur_lit += 1u;
             if ltrl.pos == pos { return Some(ltrl); }
@@ -2148,8 +2154,10 @@ pub fn next_comment(s: @ps) -> Option<comments::cmnt> {
     match s.comments {
       Some(ref cmnts) => {
         if s.cur_cmnt_and_lit.cur_cmnt < cmnts.len() {
-            return Some(copy cmnts[s.cur_cmnt_and_lit.cur_cmnt]);
-        } else { return None::<comments::cmnt>; }
+            return Some(cmnts[s.cur_cmnt_and_lit.cur_cmnt].clone());
+        } else {
+            return None::<comments::cmnt>;
+        }
       }
       _ => return None::<comments::cmnt>
     }
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 3cdc4fd0fa1..3d2e0632a33 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -21,7 +21,7 @@ pub struct Interner<T> {
 }
 
 // when traits can extend traits, we should extend index<uint,T> to get []
-impl<T:Eq + IterBytes + Hash + Freeze + Copy> Interner<T> {
+impl<T:Eq + IterBytes + Hash + Freeze + Clone> Interner<T> {
     pub fn new() -> Interner<T> {
         Interner {
             map: @mut HashMap::new(),
@@ -31,7 +31,9 @@ impl<T:Eq + IterBytes + Hash + Freeze + Copy> Interner<T> {
 
     pub fn prefill(init: &[T]) -> Interner<T> {
         let rv = Interner::new();
-        for init.iter().advance |v| { rv.intern(copy *v); }
+        for init.iter().advance |v| {
+            rv.intern((*v).clone());
+        }
         rv
     }
 
@@ -43,7 +45,7 @@ impl<T:Eq + IterBytes + Hash + Freeze + Copy> Interner<T> {
 
         let vect = &mut *self.vect;
         let new_idx = vect.len();
-        self.map.insert(copy val, new_idx);
+        self.map.insert(val.clone(), new_idx);
         vect.push(val);
         new_idx
     }
@@ -58,7 +60,9 @@ impl<T:Eq + IterBytes + Hash + Freeze + Copy> Interner<T> {
         new_idx
     }
 
-    pub fn get(&self, idx: uint) -> T { copy self.vect[idx] }
+    pub fn get(&self, idx: uint) -> T {
+        self.vect[idx].clone()
+    }
 
     pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() }
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 5c5d154a445..d68958ffa77 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -59,7 +59,7 @@ pub fn generics_of_fn(fk: &fn_kind) -> Generics {
     match *fk {
         fk_item_fn(_, generics, _, _) |
         fk_method(_, generics, _) => {
-            copy *generics
+            (*generics).clone()
         }
         fk_anon(*) | fk_fn_block(*) => {
             Generics {
@@ -94,7 +94,7 @@ pub struct Visitor<E> {
 
 pub type visitor<E> = @Visitor<E>;
 
-pub fn default_visitor<E: Copy>() -> visitor<E> {
+pub fn default_visitor<E:Clone>() -> visitor<E> {
     return @Visitor {
         visit_mod: |a,b,c,d|visit_mod::<E>(a, b, c, d),
         visit_view_item: |a,b|visit_view_item::<E>(a, b),
@@ -118,35 +118,42 @@ pub fn default_visitor<E: Copy>() -> visitor<E> {
     };
 }
 
-pub fn visit_crate<E: Copy>(c: &crate, (e, v): (E, vt<E>)) {
+pub fn visit_crate<E:Clone>(c: &crate, (e, v): (E, vt<E>)) {
     (v.visit_mod)(&c.node.module, c.span, crate_node_id, (e, v));
 }
 
-pub fn visit_mod<E: Copy>(m: &_mod, _sp: span, _id: node_id, (e, v): (E, vt<E>)) {
-    for m.view_items.iter().advance |vi| { (v.visit_view_item)(vi, (copy e, v)); }
-    for m.items.iter().advance |i| { (v.visit_item)(*i, (copy e, v)); }
+pub fn visit_mod<E:Clone>(m: &_mod,
+                          _sp: span,
+                          _id: node_id,
+                          (e, v): (E, vt<E>)) {
+    for m.view_items.iter().advance |vi| {
+        (v.visit_view_item)(vi, (e.clone(), v));
+    }
+    for m.items.iter().advance |i| {
+        (v.visit_item)(*i, (e.clone(), 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, (copy e, v));
-    (v.visit_ty)(&loc.node.ty, (copy e, v));
+pub fn visit_local<E:Clone>(loc: &local, (e, v): (E, vt<E>)) {
+    (v.visit_pat)(loc.node.pat, (e.clone(), v));
+    (v.visit_ty)(&loc.node.ty, (e.clone(), v));
     match loc.node.init {
       None => (),
       Some(ex) => (v.visit_expr)(ex, (e, v))
     }
 }
 
-fn visit_trait_ref<E: Copy>(tref: &ast::trait_ref, (e, v): (E, vt<E>)) {
+fn visit_trait_ref<E:Clone>(tref: &ast::trait_ref, (e, v): (E, vt<E>)) {
     visit_path(&tref.path, (e, v));
 }
 
-pub fn visit_item<E: Copy>(i: &item, (e, v): (E, vt<E>)) {
+pub fn visit_item<E:Clone>(i: &item, (e, v): (E, vt<E>)) {
     match i.node {
         item_static(ref t, _, ex) => {
-            (v.visit_ty)(t, (copy e, v));
-            (v.visit_expr)(ex, (copy e, v));
+            (v.visit_ty)(t, (e.clone(), v));
+            (v.visit_expr)(ex, (e.clone(), v));
         }
         item_fn(ref decl, purity, abi, ref generics, ref body) => {
             (v.visit_fn)(
@@ -166,15 +173,19 @@ 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.iter().advance |vi| { (v.visit_view_item)(vi, (copy e, v)); }
-            for nm.items.iter().advance |ni| { (v.visit_foreign_item)(*ni, (copy e, v)); }
+            for nm.view_items.iter().advance |vi| {
+                (v.visit_view_item)(vi, (e.clone(), v));
+            }
+            for nm.items.iter().advance |ni| {
+                (v.visit_foreign_item)(*ni, (e.clone(), v));
+            }
         }
         item_ty(ref t, ref tps) => {
-            (v.visit_ty)(t, (copy e, v));
+            (v.visit_ty)(t, (e.clone(), v));
             (v.visit_generics)(tps, (e, v));
         }
         item_enum(ref enum_definition, ref tps) => {
-            (v.visit_generics)(tps, (copy e, v));
+            (v.visit_generics)(tps, (e.clone(), v));
             visit_enum_def(
                 enum_definition,
                 tps,
@@ -182,55 +193,57 @@ pub fn visit_item<E: Copy>(i: &item, (e, v): (E, vt<E>)) {
             );
         }
         item_impl(ref tps, ref traits, ref ty, ref methods) => {
-            (v.visit_generics)(tps, (copy e, v));
+            (v.visit_generics)(tps, (e.clone(), v));
             for traits.iter().advance |p| {
-                visit_trait_ref(p, (copy e, v));
+                visit_trait_ref(p, (e.clone(), v));
             }
-            (v.visit_ty)(ty, (copy e, v));
+            (v.visit_ty)(ty, (e.clone(), v));
             for methods.iter().advance |m| {
-                visit_method_helper(*m, (copy e, v))
+                visit_method_helper(*m, (e.clone(), v))
             }
         }
         item_struct(struct_def, ref generics) => {
-            (v.visit_generics)(generics, (copy e, v));
+            (v.visit_generics)(generics, (e.clone(), 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, (copy e, v));
-            for traits.iter().advance |p| { visit_path(&p.path, (copy e, v)); }
+            (v.visit_generics)(generics, (e.clone(), v));
+            for traits.iter().advance |p| {
+                visit_path(&p.path, (e.clone(), v));
+            }
             for methods.iter().advance |m| {
-                (v.visit_trait_method)(m, (copy e, v));
+                (v.visit_trait_method)(m, (e.clone(), v));
             }
         }
         item_mac(ref m) => visit_mac(m, (e, v))
     }
 }
 
-pub fn visit_enum_def<E: Copy>(enum_definition: &ast::enum_def,
+pub fn visit_enum_def<E:Clone>(enum_definition: &ast::enum_def,
                                tps: &Generics,
                                (e, v): (E, vt<E>)) {
     for enum_definition.variants.iter().advance |vr| {
         match vr.node.kind {
             tuple_variant_kind(ref variant_args) => {
                 for variant_args.iter().advance |va| {
-                    (v.visit_ty)(&va.ty, (copy e, v));
+                    (v.visit_ty)(&va.ty, (e.clone(), v));
                 }
             }
             struct_variant_kind(struct_def) => {
                 (v.visit_struct_def)(struct_def, vr.node.name, tps,
-                                     vr.node.id, (copy e, v));
+                                     vr.node.id, (e.clone(), v));
             }
         }
         // Visit the disr expr if it exists
         for vr.node.disr_expr.iter().advance |ex| {
-            (v.visit_expr)(*ex, (copy e, v))
+            (v.visit_expr)(*ex, (e.clone(), v))
         }
     }
 }
 
 pub fn skip_ty<E>(_t: &Ty, (_e,_v): (E, vt<E>)) {}
 
-pub fn visit_ty<E: Copy>(t: &Ty, (e, v): (E, vt<E>)) {
+pub fn visit_ty<E:Clone>(t: &Ty, (e, v): (E, vt<E>)) {
     match t.node {
         ty_box(ref mt) | ty_uniq(ref mt) |
         ty_vec(ref mt) | ty_ptr(ref mt) | ty_rptr(_, ref mt) => {
@@ -238,92 +251,96 @@ pub fn visit_ty<E: Copy>(t: &Ty, (e, v): (E, vt<E>)) {
         },
         ty_tup(ref ts) => {
             for ts.iter().advance |tt| {
-                (v.visit_ty)(tt, (copy e, v));
+                (v.visit_ty)(tt, (e.clone(), v));
             }
         },
         ty_closure(ref f) => {
-            for f.decl.inputs.iter().advance |a| { (v.visit_ty)(&a.ty, (copy e, v)); }
-            (v.visit_ty)(&f.decl.output, (copy e, v));
+            for f.decl.inputs.iter().advance |a| {
+                (v.visit_ty)(&a.ty, (e.clone(), v));
+            }
+            (v.visit_ty)(&f.decl.output, (e.clone(), v));
             do f.bounds.map |bounds| {
-                visit_ty_param_bounds(bounds, (copy e, v));
+                visit_ty_param_bounds(bounds, (e.clone(), v));
             };
         },
         ty_bare_fn(ref f) => {
-            for f.decl.inputs.iter().advance |a| { (v.visit_ty)(&a.ty, (copy e, v)); }
+            for f.decl.inputs.iter().advance |a| {
+                (v.visit_ty)(&a.ty, (e.clone(), v));
+            }
             (v.visit_ty)(&f.decl.output, (e, v));
         },
         ty_path(ref p, ref bounds, _) => {
-            visit_path(p, (copy e, v));
+            visit_path(p, (e.clone(), v));
             do bounds.map |bounds| {
-                visit_ty_param_bounds(bounds, (copy e, v));
+                visit_ty_param_bounds(bounds, (e.clone(), v));
             };
         },
         ty_fixed_length_vec(ref mt, ex) => {
-            (v.visit_ty)(mt.ty, (copy e, v));
-            (v.visit_expr)(ex, (copy e, v));
+            (v.visit_ty)(mt.ty, (e.clone(), v));
+            (v.visit_expr)(ex, (e.clone(), 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.iter().advance |tp| { (v.visit_ty)(tp, (copy e, v)); }
+pub fn visit_path<E:Clone>(p: &Path, (e, v): (E, vt<E>)) {
+    for p.types.iter().advance |tp| { (v.visit_ty)(tp, (e.clone(), v)); }
 }
 
-pub fn visit_pat<E: Copy>(p: &pat, (e, v): (E, vt<E>)) {
+pub fn visit_pat<E:Clone>(p: &pat, (e, v): (E, vt<E>)) {
     match p.node {
         pat_enum(ref path, ref children) => {
-            visit_path(path, (copy e, v));
+            visit_path(path, (e.clone(), v));
             for children.iter().advance |children| {
                 for children.iter().advance |child| {
-                    (v.visit_pat)(*child, (copy e, v));
+                    (v.visit_pat)(*child, (e.clone(), v));
                 }
             }
         }
         pat_struct(ref path, ref fields, _) => {
-            visit_path(path, (copy e, v));
+            visit_path(path, (e.clone(), v));
             for fields.iter().advance |f| {
-                (v.visit_pat)(f.pat, (copy e, v));
+                (v.visit_pat)(f.pat, (e.clone(), v));
             }
         }
         pat_tup(ref elts) => {
             for elts.iter().advance |elt| {
-                (v.visit_pat)(*elt, (copy e, v))
+                (v.visit_pat)(*elt, (e.clone(), v))
             }
         },
         pat_box(inner) | pat_uniq(inner) | pat_region(inner) => {
             (v.visit_pat)(inner, (e, v))
         },
         pat_ident(_, ref path, ref inner) => {
-            visit_path(path, (copy e, v));
+            visit_path(path, (e.clone(), v));
             for inner.iter().advance |subpat| {
-                (v.visit_pat)(*subpat, (copy e, v))
+                (v.visit_pat)(*subpat, (e.clone(), v))
             }
         }
         pat_lit(ex) => (v.visit_expr)(ex, (e, v)),
         pat_range(e1, e2) => {
-            (v.visit_expr)(e1, (copy e, v));
+            (v.visit_expr)(e1, (e.clone(), v));
             (v.visit_expr)(e2, (e, v));
         }
         pat_wild => (),
         pat_vec(ref before, ref slice, ref after) => {
             for before.iter().advance |elt| {
-                (v.visit_pat)(*elt, (copy e, v));
+                (v.visit_pat)(*elt, (e.clone(), v));
             }
             for slice.iter().advance |elt| {
-                (v.visit_pat)(*elt, (copy e, v));
+                (v.visit_pat)(*elt, (e.clone(), v));
             }
             for after.iter().advance |tail| {
-                (v.visit_pat)(*tail, (copy e, v));
+                (v.visit_pat)(*tail, (e.clone(), v));
             }
         }
     }
 }
 
-pub fn visit_foreign_item<E: Copy>(ni: &foreign_item, (e, v): (E, vt<E>)) {
+pub fn visit_foreign_item<E:Clone>(ni: &foreign_item, (e, v): (E, vt<E>)) {
     match ni.node {
         foreign_item_fn(ref fd, _, ref generics) => {
-            visit_fn_decl(fd, (copy e, v));
+            visit_fn_decl(fd, (e.clone(), v));
             (v.visit_generics)(generics, (e, v));
         }
         foreign_item_static(ref t, _) => {
@@ -332,26 +349,26 @@ pub fn visit_foreign_item<E: Copy>(ni: &foreign_item, (e, v): (E, vt<E>)) {
     }
 }
 
-pub fn visit_ty_param_bounds<E: Copy>(bounds: &OptVec<TyParamBound>,
+pub fn visit_ty_param_bounds<E:Clone>(bounds: &OptVec<TyParamBound>,
                                       (e, v): (E, vt<E>)) {
     for bounds.iter().advance |bound| {
         match *bound {
-            TraitTyParamBound(ref ty) => visit_trait_ref(ty, (copy e, v)),
+            TraitTyParamBound(ref ty) => visit_trait_ref(ty, (e.clone(), v)),
             RegionTyParamBound => {}
         }
     }
 }
 
-pub fn visit_generics<E: Copy>(generics: &Generics, (e, v): (E, vt<E>)) {
+pub fn visit_generics<E:Clone>(generics: &Generics, (e, v): (E, vt<E>)) {
     for generics.ty_params.iter().advance |tp| {
-        visit_ty_param_bounds(&tp.bounds, (copy e, v));
+        visit_ty_param_bounds(&tp.bounds, (e.clone(), v));
     }
 }
 
-pub fn visit_fn_decl<E: Copy>(fd: &fn_decl, (e, v): (E, vt<E>)) {
+pub fn visit_fn_decl<E:Clone>(fd: &fn_decl, (e, v): (E, vt<E>)) {
     for fd.inputs.iter().advance |a| {
-        (v.visit_pat)(a.pat, (copy e, v));
-        (v.visit_ty)(&a.ty, (copy e, v));
+        (v.visit_pat)(a.pat, (e.clone(), v));
+        (v.visit_ty)(&a.ty, (e.clone(), v));
     }
     (v.visit_ty)(&fd.output, (e, v));
 }
@@ -360,7 +377,7 @@ pub fn visit_fn_decl<E: Copy>(fd: &fn_decl, (e, v): (E, vt<E>)) {
 // visit_fn() and check for fk_method().  I named this visit_method_helper()
 // because it is not a default impl of any method, though I doubt that really
 // clarifies anything. - Niko
-pub fn visit_method_helper<E: Copy>(m: &method, (e, v): (E, vt<E>)) {
+pub fn visit_method_helper<E:Clone>(m: &method, (e, v): (E, vt<E>)) {
     (v.visit_fn)(&fk_method(m.ident, &m.generics, m),
                  &m.decl,
                  &m.body,
@@ -369,28 +386,30 @@ pub fn visit_method_helper<E: Copy>(m: &method, (e, v): (E, vt<E>)) {
                  (e, v));
 }
 
-pub fn visit_fn<E: Copy>(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span,
+pub fn visit_fn<E:Clone>(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span,
                          _id: node_id, (e, v): (E, vt<E>)) {
-    visit_fn_decl(decl, (copy e, v));
+    visit_fn_decl(decl, (e.clone(), v));
     let generics = generics_of_fn(fk);
-    (v.visit_generics)(&generics, (copy e, v));
+    (v.visit_generics)(&generics, (e.clone(), 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.iter().advance |a| { (v.visit_ty)(&a.ty, (copy e, v)); }
-    (v.visit_generics)(&m.generics, (copy e, v));
+pub fn visit_ty_method<E:Clone>(m: &ty_method, (e, v): (E, vt<E>)) {
+    for m.decl.inputs.iter().advance |a| {
+        (v.visit_ty)(&a.ty, (e.clone(), v));
+    }
+    (v.visit_generics)(&m.generics, (e.clone(), v));
     (v.visit_ty)(&m.decl.output, (e, v));
 }
 
-pub fn visit_trait_method<E: Copy>(m: &trait_method, (e, v): (E, vt<E>)) {
+pub fn visit_trait_method<E:Clone>(m: &trait_method, (e, v): (E, vt<E>)) {
     match *m {
       required(ref ty_m) => (v.visit_ty_method)(ty_m, (e, v)),
       provided(m) => visit_method_helper(m, (e, v))
     }
 }
 
-pub fn visit_struct_def<E: Copy>(
+pub fn visit_struct_def<E:Clone>(
     sd: @struct_def,
     _nm: ast::ident,
     _generics: &Generics,
@@ -398,20 +417,20 @@ pub fn visit_struct_def<E: Copy>(
     (e, v): (E, vt<E>)
 ) {
     for sd.fields.iter().advance |f| {
-        (v.visit_struct_field)(*f, (copy e, v));
+        (v.visit_struct_field)(*f, (e.clone(), v));
     }
 }
 
-pub fn visit_struct_field<E: Copy>(sf: &struct_field, (e, v): (E, vt<E>)) {
+pub fn visit_struct_field<E:Clone>(sf: &struct_field, (e, v): (E, vt<E>)) {
     (v.visit_ty)(&sf.node.ty, (e, v));
 }
 
-pub fn visit_block<E: Copy>(b: &blk, (e, v): (E, vt<E>)) {
+pub fn visit_block<E:Clone>(b: &blk, (e, v): (E, vt<E>)) {
     for b.view_items.iter().advance |vi| {
-        (v.visit_view_item)(vi, (copy e, v));
+        (v.visit_view_item)(vi, (e.clone(), v));
     }
     for b.stmts.iter().advance |s| {
-        (v.visit_stmt)(*s, (copy e, v));
+        (v.visit_stmt)(*s, (e.clone(), v));
     }
     visit_expr_opt(b.expr, (e, v));
 }
@@ -425,7 +444,7 @@ pub fn visit_stmt<E>(s: &stmt, (e, v): (E, vt<E>)) {
     }
 }
 
-pub fn visit_decl<E: Copy>(d: &decl, (e, v): (E, vt<E>)) {
+pub fn visit_decl<E:Clone>(d: &decl, (e, v): (E, vt<E>)) {
     match d.node {
         decl_local(ref loc) => (v.visit_local)(*loc, (e, v)),
         decl_item(it) => (v.visit_item)(it, (e, v))
@@ -436,67 +455,67 @@ pub fn visit_expr_opt<E>(eo: Option<@expr>, (e, v): (E, vt<E>)) {
     match eo { None => (), Some(ex) => (v.visit_expr)(ex, (e, v)) }
 }
 
-pub fn visit_exprs<E: Copy>(exprs: &[@expr], (e, v): (E, vt<E>)) {
-    for exprs.iter().advance |ex| { (v.visit_expr)(*ex, (copy e, v)); }
+pub fn visit_exprs<E:Clone>(exprs: &[@expr], (e, v): (E, vt<E>)) {
+    for exprs.iter().advance |ex| { (v.visit_expr)(*ex, (e.clone(), v)); }
 }
 
 pub fn visit_mac<E>(_m: &mac, (_e, _v): (E, vt<E>)) {
     /* no user-serviceable parts inside */
 }
 
-pub fn visit_expr<E: Copy>(ex: @expr, (e, v): (E, vt<E>)) {
+pub fn visit_expr<E:Clone>(ex: @expr, (e, v): (E, vt<E>)) {
     match ex.node {
-        expr_vstore(x, _) => (v.visit_expr)(x, (copy e, v)),
-        expr_vec(ref es, _) => visit_exprs(*es, (copy e, v)),
+        expr_vstore(x, _) => (v.visit_expr)(x, (e.clone(), v)),
+        expr_vec(ref es, _) => visit_exprs(*es, (e.clone(), v)),
         expr_repeat(element, count, _) => {
-            (v.visit_expr)(element, (copy e, v));
-            (v.visit_expr)(count, (copy e, v));
+            (v.visit_expr)(element, (e.clone(), v));
+            (v.visit_expr)(count, (e.clone(), v));
         }
         expr_struct(ref p, ref flds, base) => {
-            visit_path(p, (copy e, v));
+            visit_path(p, (e.clone(), v));
             for flds.iter().advance |f| {
-                (v.visit_expr)(f.node.expr, (copy e, v));
+                (v.visit_expr)(f.node.expr, (e.clone(), v));
             }
-            visit_expr_opt(base, (copy e, v));
+            visit_expr_opt(base, (e.clone(), v));
         }
         expr_tup(ref elts) => {
-            for elts.iter().advance |el| { (v.visit_expr)(*el, (copy e, v)) }
+            for elts.iter().advance |el| { (v.visit_expr)(*el, (e.clone(), v)) }
         }
         expr_call(callee, ref args, _) => {
-            visit_exprs(*args, (copy e, v));
-            (v.visit_expr)(callee, (copy e, v));
+            visit_exprs(*args, (e.clone(), v));
+            (v.visit_expr)(callee, (e.clone(), v));
         }
         expr_method_call(_, callee, _, ref tys, ref args, _) => {
-            visit_exprs(*args, (copy e, v));
+            visit_exprs(*args, (e.clone(), v));
             for tys.iter().advance |tp| {
-                (v.visit_ty)(tp, (copy e, v));
+                (v.visit_ty)(tp, (e.clone(), v));
             }
-            (v.visit_expr)(callee, (copy e, v));
+            (v.visit_expr)(callee, (e.clone(), v));
         }
         expr_binary(_, _, a, b) => {
-            (v.visit_expr)(a, (copy e, v));
-            (v.visit_expr)(b, (copy e, v));
+            (v.visit_expr)(a, (e.clone(), v));
+            (v.visit_expr)(b, (e.clone(), v));
         }
         expr_addr_of(_, x) | expr_unary(_, _, x) |
-        expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (copy e, v)),
+        expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (e.clone(), v)),
         expr_lit(_) => (),
         expr_cast(x, ref t) => {
-            (v.visit_expr)(x, (copy e, v));
-            (v.visit_ty)(t, (copy e, v));
+            (v.visit_expr)(x, (e.clone(), v));
+            (v.visit_ty)(t, (e.clone(), v));
         }
         expr_if(x, ref b, eo) => {
-            (v.visit_expr)(x, (copy e, v));
-            (v.visit_block)(b, (copy e, v));
-            visit_expr_opt(eo, (copy e, v));
+            (v.visit_expr)(x, (e.clone(), v));
+            (v.visit_block)(b, (e.clone(), v));
+            visit_expr_opt(eo, (e.clone(), v));
         }
         expr_while(x, ref b) => {
-            (v.visit_expr)(x, (copy e, v));
-            (v.visit_block)(b, (copy e, v));
+            (v.visit_expr)(x, (e.clone(), v));
+            (v.visit_block)(b, (e.clone(), v));
         }
-        expr_loop(ref b, _) => (v.visit_block)(b, (copy e, v)),
+        expr_loop(ref b, _) => (v.visit_block)(b, (e.clone(), v)),
         expr_match(x, ref arms) => {
-            (v.visit_expr)(x, (copy e, v));
-            for arms.iter().advance |a| { (v.visit_arm)(a, (copy e, v)); }
+            (v.visit_expr)(x, (e.clone(), v));
+            for arms.iter().advance |a| { (v.visit_arm)(a, (e.clone(), v)); }
         }
         expr_fn_block(ref decl, ref body) => {
             (v.visit_fn)(
@@ -505,56 +524,56 @@ pub fn visit_expr<E: Copy>(ex: @expr, (e, v): (E, vt<E>)) {
                 body,
                 ex.span,
                 ex.id,
-                (copy e, v)
+                (e.clone(), v)
             );
         }
-        expr_block(ref b) => (v.visit_block)(b, (copy e, v)),
+        expr_block(ref b) => (v.visit_block)(b, (e.clone(), v)),
         expr_assign(a, b) => {
-            (v.visit_expr)(b, (copy e, v));
-            (v.visit_expr)(a, (copy e, v));
+            (v.visit_expr)(b, (e.clone(), v));
+            (v.visit_expr)(a, (e.clone(), v));
         }
-        expr_copy(a) => (v.visit_expr)(a, (copy e, v)),
+        expr_copy(a) => (v.visit_expr)(a, (e.clone(), v)),
         expr_assign_op(_, _, a, b) => {
-            (v.visit_expr)(b, (copy e, v));
-            (v.visit_expr)(a, (copy e, v));
+            (v.visit_expr)(b, (e.clone(), v));
+            (v.visit_expr)(a, (e.clone(), v));
         }
         expr_field(x, _, ref tys) => {
-            (v.visit_expr)(x, (copy e, v));
+            (v.visit_expr)(x, (e.clone(), v));
             for tys.iter().advance |tp| {
-                (v.visit_ty)(tp, (copy e, v));
+                (v.visit_ty)(tp, (e.clone(), v));
             }
         }
         expr_index(_, a, b) => {
-            (v.visit_expr)(a, (copy e, v));
-            (v.visit_expr)(b, (copy e, v));
+            (v.visit_expr)(a, (e.clone(), v));
+            (v.visit_expr)(b, (e.clone(), v));
         }
-        expr_path(ref p) => visit_path(p, (copy e, v)),
+        expr_path(ref p) => visit_path(p, (e.clone(), v)),
         expr_self => (),
         expr_break(_) => (),
         expr_again(_) => (),
-        expr_ret(eo) => visit_expr_opt(eo, (copy e, v)),
+        expr_ret(eo) => visit_expr_opt(eo, (e.clone(), v)),
         expr_log(lv, x) => {
-            (v.visit_expr)(lv, (copy e, v));
-            (v.visit_expr)(x, (copy e, v));
+            (v.visit_expr)(lv, (e.clone(), v));
+            (v.visit_expr)(x, (e.clone(), v));
         }
-        expr_mac(ref mac) => visit_mac(mac, (copy e, v)),
-        expr_paren(x) => (v.visit_expr)(x, (copy e, v)),
+        expr_mac(ref mac) => visit_mac(mac, (e.clone(), v)),
+        expr_paren(x) => (v.visit_expr)(x, (e.clone(), v)),
         expr_inline_asm(ref a) => {
             for a.inputs.iter().advance |&(_, in)| {
-                (v.visit_expr)(in, (copy e, v));
+                (v.visit_expr)(in, (e.clone(), v));
             }
             for a.outputs.iter().advance |&(_, out)| {
-                (v.visit_expr)(out, (copy e, v));
+                (v.visit_expr)(out, (e.clone(), v));
             }
         }
     }
     (v.visit_expr_post)(ex, (e, v));
 }
 
-pub fn visit_arm<E: Copy>(a: &arm, (e, v): (E, vt<E>)) {
-    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));
+pub fn visit_arm<E:Clone>(a: &arm, (e, v): (E, vt<E>)) {
+    for a.pats.iter().advance |p| { (v.visit_pat)(*p, (e.clone(), v)); }
+    visit_expr_opt(a.guard, (e.clone(), v));
+    (v.visit_block)(&a.body, (e.clone(), v));
 }
 
 // Simpler, non-context passing interface. Always walks the whole tree, simply