about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-02-19 12:24:30 -0800
committerbors <bors@rust-lang.org>2013-02-19 12:24:30 -0800
commit1f956fc3b2ad6f1b8db3d580a409fb5636c8297f (patch)
tree432dbd8dd2a3a2e0434cd4a9fc5c66e8718776ad /src/libsyntax
parenta782efc4f16fed52f1f82af5869bfb5285bbc3f4 (diff)
parent68746cd4fb93e95a393c539abc65b93ed5eecdb5 (diff)
downloadrust-1f956fc3b2ad6f1b8db3d580a409fb5636c8297f.tar.gz
rust-1f956fc3b2ad6f1b8db3d580a409fb5636c8297f.zip
auto merge of #4999 : erickt/rust/incoming, r=brson
This patch series is doing a couple things with the ultimate goal of removing `#[allow(vecs_implicitly_copyable)]`, although I'm not quite there yet. The main change is passing around `@~str`s in most places, and using `ref`s in others. As far as I could tell, there are no performance changes with these patches, and all the tests pass on my mac.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/ast_map.rs6
-rw-r--r--src/libsyntax/ast_util.rs4
-rw-r--r--src/libsyntax/attr.rs157
-rw-r--r--src/libsyntax/ext/auto_encode.rs38
-rw-r--r--src/libsyntax/ext/base.rs54
-rw-r--r--src/libsyntax/ext/expand.rs28
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs5
-rw-r--r--src/libsyntax/ext/pipes/check.rs14
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs27
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs11
-rw-r--r--src/libsyntax/fold.rs98
-rw-r--r--src/libsyntax/parse/attr.rs32
-rw-r--r--src/libsyntax/parse/comments.rs6
-rw-r--r--src/libsyntax/parse/parser.rs14
-rw-r--r--src/libsyntax/parse/token.rs4
-rw-r--r--src/libsyntax/print/pprust.rs62
-rw-r--r--src/libsyntax/util/interner.rs74
-rw-r--r--src/libsyntax/visit.rs62
19 files changed, 369 insertions, 333 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index bf64402d237..234cef5f6eb 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -173,9 +173,9 @@ pub type meta_item = spanned<meta_item_>;
 #[auto_decode]
 #[deriving_eq]
 pub enum meta_item_ {
-    meta_word(~str),
-    meta_list(~str, ~[@meta_item]),
-    meta_name_value(~str, lit),
+    meta_word(@~str),
+    meta_list(@~str, ~[@meta_item]),
+    meta_name_value(@~str, lit),
 }
 
 pub type blk = spanned<blk_>;
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 108a0dfc5e0..74f67808a5e 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -193,7 +193,7 @@ pub fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
         cx.local_id += 1u;
     }
     match fk {
-        visit::fk_dtor(tps, ref attrs, self_id, parent_id) => {
+        visit::fk_dtor(ref tps, ref attrs, self_id, parent_id) => {
             let dt = @spanned {
                 node: ast::struct_dtor_ {
                     id: id,
@@ -203,7 +203,7 @@ pub fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
                 },
                 span: sp,
             };
-            cx.map.insert(id, node_dtor(/* FIXME (#2543) */ copy tps, dt,
+            cx.map.insert(id, node_dtor(/* FIXME (#2543) */ copy *tps, dt,
                                         parent_id,
                                         @/* FIXME (#2543) */ copy cx.path));
       }
@@ -286,7 +286,7 @@ pub fn map_item(i: @item, &&cx: @mut Ctx, v: vt) {
         map_struct_def(struct_def, node_item(i, item_path), i.ident, cx,
                        v);
       }
-      item_trait(_, traits, ref methods) => {
+      item_trait(_, ref traits, ref methods) => {
         for traits.each |p| {
             cx.map.insert(p.ref_id, node_item(i, item_path));
         }
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 9f7b28c36f5..a82ad762e22 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -327,8 +327,8 @@ pub impl inlined_item_utils for inlined_item {
             ii_item(i) => (v.visit_item)(i, e, v),
             ii_foreign(i) => (v.visit_foreign_item)(i, e, v),
             ii_method(_, m) => visit::visit_method_helper(m, e, v),
-            ii_dtor(ref dtor, _, tps, parent_id) => {
-              visit::visit_struct_dtor_helper((*dtor), tps, parent_id, e, v);
+            ii_dtor(/*bad*/ copy dtor, _, /*bad*/ copy tps, parent_id) => {
+                visit::visit_struct_dtor_helper(dtor, tps, parent_id, e, v);
             }
         }
     }
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 605d944c70d..14ffb1cab5d 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -29,24 +29,24 @@ use std;
 
 /* Constructors */
 
-pub fn mk_name_value_item_str(name: ~str, value: ~str)
+pub fn mk_name_value_item_str(name: @~str, value: @~str)
                            -> @ast::meta_item {
-    let value_lit = dummy_spanned(ast::lit_str(@value));
-    return mk_name_value_item(name, value_lit);
+    let value_lit = dummy_spanned(ast::lit_str(value));
+    mk_name_value_item(name, value_lit)
 }
 
-pub fn mk_name_value_item(name: ~str, +value: ast::lit)
+pub fn mk_name_value_item(name: @~str, +value: ast::lit)
         -> @ast::meta_item {
-    return @dummy_spanned(ast::meta_name_value(name, value));
+    @dummy_spanned(ast::meta_name_value(name, value))
 }
 
-pub fn mk_list_item(name: ~str, +items: ~[@ast::meta_item]) ->
+pub fn mk_list_item(name: @~str, +items: ~[@ast::meta_item]) ->
    @ast::meta_item {
-    return @dummy_spanned(ast::meta_list(name, items));
+    @dummy_spanned(ast::meta_list(name, items))
 }
 
-pub fn mk_word_item(name: ~str) -> @ast::meta_item {
-    return @dummy_spanned(ast::meta_word(name));
+pub fn mk_word_item(name: @~str) -> @ast::meta_item {
+    @dummy_spanned(ast::meta_word(name))
 }
 
 pub fn mk_attr(item: @ast::meta_item) -> ast::attribute {
@@ -60,7 +60,7 @@ pub fn mk_sugared_doc_attr(text: ~str,
     let lit = spanned(lo, hi, ast::lit_str(@text));
     let attr = ast::attribute_ {
         style: doc_comment_style(text),
-        value: spanned(lo, hi, ast::meta_name_value(~"doc", lit)),
+        value: spanned(lo, hi, ast::meta_name_value(@~"doc", lit)),
         is_sugared_doc: true
     };
     spanned(lo, hi, attr)
@@ -80,9 +80,9 @@ pub fn attr_metas(attrs: ~[ast::attribute]) -> ~[@ast::meta_item] {
 pub fn desugar_doc_attr(attr: &ast::attribute) -> ast::attribute {
     if attr.node.is_sugared_doc {
         let comment = get_meta_item_value_str(@attr.node.value).get();
-        let meta = mk_name_value_item_str(~"doc",
-                                     strip_doc_comment_decoration(comment));
-        return mk_attr(meta);
+        let meta = mk_name_value_item_str(@~"doc",
+                                     @strip_doc_comment_decoration(*comment));
+        mk_attr(meta)
     } else {
         *attr
     }
@@ -90,15 +90,15 @@ pub fn desugar_doc_attr(attr: &ast::attribute) -> ast::attribute {
 
 /* Accessors */
 
-pub fn get_attr_name(attr: ast::attribute) -> ~str {
+pub pure fn get_attr_name(attr: &ast::attribute) -> @~str {
     get_meta_item_name(@attr.node.value)
 }
 
-pub fn get_meta_item_name(meta: @ast::meta_item) -> ~str {
+pub pure fn get_meta_item_name(meta: @ast::meta_item) -> @~str {
     match meta.node {
-      ast::meta_word(ref n) => (*n),
-      ast::meta_name_value(ref n, _) => (*n),
-      ast::meta_list(ref n, _) => (*n)
+        ast::meta_word(n) => n,
+        ast::meta_name_value(n, _) => n,
+        ast::meta_list(n, _) => n,
     }
 }
 
@@ -106,13 +106,15 @@ pub fn get_meta_item_name(meta: @ast::meta_item) -> ~str {
  * Gets the string value if the meta_item is a meta_name_value variant
  * containing a string, otherwise none
  */
-pub fn get_meta_item_value_str(meta: @ast::meta_item) -> Option<~str> {
+pub fn get_meta_item_value_str(meta: @ast::meta_item) -> Option<@~str> {
     match meta.node {
-        ast::meta_name_value(_, v) => match v.node {
-            ast::lit_str(s) => option::Some(*s),
-            _ => option::None
+        ast::meta_name_value(_, v) => {
+            match v.node {
+                ast::lit_str(s) => Some(s),
+                _ => None,
+            }
         },
-        _ => option::None
+        _ => None
     }
 }
 
@@ -130,11 +132,11 @@ pub fn get_meta_item_list(meta: @ast::meta_item)
  * a tuple containing the name and string value, otherwise `none`
  */
 pub fn get_name_value_str_pair(item: @ast::meta_item)
-                            -> Option<(~str, ~str)> {
+                            -> Option<(@~str, @~str)> {
     match attr::get_meta_item_value_str(item) {
-      Some(ref value) => {
+      Some(value) => {
         let name = attr::get_meta_item_name(item);
-        Some((name, (*value)))
+        Some((name, value))
       }
       None => None
     }
@@ -146,14 +148,13 @@ pub fn get_name_value_str_pair(item: @ast::meta_item)
 /// Search a list of attributes and return only those with a specific name
 pub fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) ->
    ~[ast::attribute] {
-    let filter: &fn(a: &ast::attribute) -> Option<ast::attribute> = |a| {
-        if name == get_attr_name(*a) {
-            option::Some(*a)
+    do vec::filter_mapped(attrs) |a| {
+        if name == *get_attr_name(a) {
+            Some(*a)
         } else {
-            option::None
+            None
         }
-    };
-    return vec::filter_mapped(attrs, filter);
+    }
 }
 
 /// Search a list of meta items and return only those with a specific name
@@ -161,7 +162,7 @@ pub fn find_meta_items_by_name(metas: &[@ast::meta_item], name: &str) ->
    ~[@ast::meta_item] {
     let mut rs = ~[];
     for metas.each |mi| {
-        if name == get_meta_item_name(*mi) {
+        if name == *get_meta_item_name(*mi) {
             rs.push(*mi)
         }
     }
@@ -214,36 +215,39 @@ pub fn attrs_contains_name(attrs: &[ast::attribute], name: &str) -> bool {
     !find_attrs_by_name(attrs, name).is_empty()
 }
 
-pub fn first_attr_value_str_by_name(attrs: ~[ast::attribute], name: ~str)
-                                 -> Option<~str> {
+pub fn first_attr_value_str_by_name(attrs: ~[ast::attribute], name: &str)
+                                 -> Option<@~str> {
 
     let mattrs = find_attrs_by_name(attrs, name);
-    if vec::len(mattrs) > 0u {
-        return get_meta_item_value_str(attr_meta(mattrs[0]));
+    if mattrs.len() > 0 {
+        get_meta_item_value_str(attr_meta(mattrs[0]))
+    } else {
+        None
     }
-    return option::None;
 }
 
-fn last_meta_item_by_name(items: ~[@ast::meta_item], name: ~str)
+fn last_meta_item_by_name(items: ~[@ast::meta_item], name: &str)
     -> Option<@ast::meta_item> {
 
     let items = attr::find_meta_items_by_name(items, name);
     vec::last_opt(items)
 }
 
-pub fn last_meta_item_value_str_by_name(items: ~[@ast::meta_item], name: ~str)
-                                     -> Option<~str> {
+pub fn last_meta_item_value_str_by_name(items: ~[@ast::meta_item], name: &str)
+                                     -> Option<@~str> {
 
     match last_meta_item_by_name(items, name) {
-      Some(item) => match attr::get_meta_item_value_str(item) {
-        Some(ref value) => Some((*value)),
+        Some(item) => {
+            match attr::get_meta_item_value_str(item) {
+                Some(value) => Some(value),
+                None => None
+            }
+        },
         None => None
-      },
-      None => None
     }
 }
 
-pub fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: ~str)
+pub fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: &str)
     -> Option<~[@ast::meta_item]> {
 
     match last_meta_item_by_name(items, name) {
@@ -256,20 +260,11 @@ pub fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: ~str)
 /* Higher-level applications */
 
 pub fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] {
-    pure fn lteq(ma: &@ast::meta_item, mb: &@ast::meta_item) -> bool {
-        pure fn key(m: &ast::meta_item) -> ~str {
-            match m.node {
-              ast::meta_word(ref name) => (*name),
-              ast::meta_name_value(ref name, _) => (*name),
-              ast::meta_list(ref name, _) => (*name)
-            }
-        }
-        key(*ma) <= key(*mb)
-    }
-
     // This is sort of stupid here, converting to a vec of mutables and back
-    let mut v: ~[@ast::meta_item] = items;
-    std::sort::quick_sort(v, lteq);
+    let mut v = items;
+    do std::sort::quick_sort(v) |ma, mb| {
+        get_meta_item_name(*ma) <= get_meta_item_name(*mb)
+    }
 
     // There doesn't seem to be a more optimal way to do this
     do v.map |&m| {
@@ -283,14 +278,14 @@ pub fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] {
     }
 }
 
-pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) ->
+pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: &str) ->
    ~[@ast::meta_item] {
 
     return vec::filter_mapped(items, |item| {
-        if get_meta_item_name(*item) != name {
-            option::Some(*item)
+        if name != *get_meta_item_name(*item) {
+            Some(*item)
         } else {
-            option::None
+            None
         }
     });
 }
@@ -311,21 +306,21 @@ pub fn find_linkage_metas(attrs: &[ast::attribute]) -> ~[@ast::meta_item] {
 pub fn foreign_abi(attrs: ~[ast::attribute])
                 -> Either<~str, ast::foreign_abi> {
     return match attr::first_attr_value_str_by_name(attrs, ~"abi") {
-      option::None => {
-        either::Right(ast::foreign_abi_cdecl)
-      }
-      option::Some(~"rust-intrinsic") => {
-        either::Right(ast::foreign_abi_rust_intrinsic)
-      }
-      option::Some(~"cdecl") => {
-        either::Right(ast::foreign_abi_cdecl)
-      }
-      option::Some(~"stdcall") => {
-        either::Right(ast::foreign_abi_stdcall)
-      }
-      option::Some(ref t) => {
-        either::Left(~"unsupported abi: " + (*t))
-      }
+        None => {
+            Right(ast::foreign_abi_cdecl)
+        }
+        Some(@~"rust-intrinsic") => {
+            Right(ast::foreign_abi_rust_intrinsic)
+        }
+        Some(@~"cdecl") => {
+            Right(ast::foreign_abi_cdecl)
+        }
+        Some(@~"stdcall") => {
+            Right(ast::foreign_abi_stdcall)
+        }
+        Some(t) => {
+            Left(~"unsupported abi: " + *t)
+        }
     };
 }
 
@@ -348,8 +343,8 @@ pub fn find_inline_attr(attrs: &[ast::attribute]) -> inline_attr {
     // FIXME (#2809)---validate the usage of #[inline] and #[inline(always)]
     do vec::foldl(ia_none, attrs) |ia,attr| {
         match attr.node.value.node {
-          ast::meta_word(~"inline") => ia_hint,
-          ast::meta_list(~"inline", items) => {
+          ast::meta_word(@~"inline") => ia_hint,
+          ast::meta_list(@~"inline", items) => {
             if !vec::is_empty(find_meta_items_by_name(items, ~"always")) {
                 ia_always
             } else if !vec::is_empty(
@@ -374,7 +369,7 @@ pub fn require_unique_names(diagnostic: span_handler,
         // FIXME: How do I silence the warnings? --pcw (#2619)
         if !set.insert(name) {
             diagnostic.span_fatal(meta.span,
-                                  fmt!("duplicate meta item `%s`", name));
+                                  fmt!("duplicate meta item `%s`", *name));
         }
     }
 }
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 9c0550c9875..9ceaebe6dd1 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -114,7 +114,7 @@ pub fn expand_auto_encode(
     in_items: ~[@ast::item]
 ) -> ~[@ast::item] {
     fn is_auto_encode(a: &ast::attribute) -> bool {
-        attr::get_attr_name(*a) == ~"auto_encode"
+        *attr::get_attr_name(a) == ~"auto_encode"
     }
 
     fn filter_attrs(item: @ast::item) -> @ast::item {
@@ -127,24 +127,24 @@ pub fn expand_auto_encode(
     do vec::flat_map(in_items) |item| {
         if item.attrs.any(is_auto_encode) {
             match item.node {
-                ast::item_struct(@ast::struct_def { fields, _}, tps) => {
+                ast::item_struct(ref struct_def, ref tps) => {
                     let ser_impl = mk_struct_ser_impl(
                         cx,
                         item.span,
                         item.ident,
-                        fields,
-                        tps
+                        struct_def.fields,
+                        *tps
                     );
 
                     ~[filter_attrs(*item), ser_impl]
                 },
-                ast::item_enum(ref enum_def, tps) => {
+                ast::item_enum(ref enum_def, ref tps) => {
                     let ser_impl = mk_enum_ser_impl(
                         cx,
                         item.span,
                         item.ident,
-                        (*enum_def),
-                        tps
+                        *enum_def,
+                        *tps
                     );
 
                     ~[filter_attrs(*item), ser_impl]
@@ -169,7 +169,7 @@ pub fn expand_auto_decode(
     in_items: ~[@ast::item]
 ) -> ~[@ast::item] {
     fn is_auto_decode(a: &ast::attribute) -> bool {
-        attr::get_attr_name(*a) == ~"auto_decode"
+        *attr::get_attr_name(a) == ~"auto_decode"
     }
 
     fn filter_attrs(item: @ast::item) -> @ast::item {
@@ -182,24 +182,24 @@ pub fn expand_auto_decode(
     do vec::flat_map(in_items) |item| {
         if item.attrs.any(is_auto_decode) {
             match item.node {
-                ast::item_struct(@ast::struct_def { fields, _}, tps) => {
+                ast::item_struct(ref struct_def, ref tps) => {
                     let deser_impl = mk_struct_deser_impl(
                         cx,
                         item.span,
                         item.ident,
-                        fields,
-                        tps
+                        struct_def.fields,
+                        *tps
                     );
 
                     ~[filter_attrs(*item), deser_impl]
                 },
-                ast::item_enum(ref enum_def, tps) => {
+                ast::item_enum(ref enum_def, ref tps) => {
                     let deser_impl = mk_enum_deser_impl(
                         cx,
                         item.span,
                         item.ident,
-                        (*enum_def),
-                        tps
+                        *enum_def,
+                        *tps
                     );
 
                     ~[filter_attrs(*item), deser_impl]
@@ -410,7 +410,7 @@ fn mk_impl(
     ident: ast::ident,
     ty_param: ast::ty_param,
     path: @ast::path,
-    tps: ~[ast::ty_param],
+    tps: &[ast::ty_param],
     f: fn(@ast::Ty) -> @ast::method
 ) -> @ast::item {
     // All the type parameters need to bound to the trait.
@@ -458,7 +458,7 @@ fn mk_ser_impl(
     cx: ext_ctxt,
     span: span,
     ident: ast::ident,
-    tps: ~[ast::ty_param],
+    tps: &[ast::ty_param],
     body: @ast::expr
 ) -> @ast::item {
     // Make a path to the std::serialize::Encodable typaram.
@@ -666,8 +666,8 @@ fn mk_struct_ser_impl(
     cx: ext_ctxt,
     span: span,
     ident: ast::ident,
-    fields: ~[@ast::struct_field],
-    tps: ~[ast::ty_param]
+    fields: &[@ast::struct_field],
+    tps: &[ast::ty_param]
 ) -> @ast::item {
     let fields = do mk_struct_fields(fields).mapi |idx, field| {
         // ast for `|| self.$(name).encode(__s)`
@@ -808,7 +808,7 @@ struct field {
     mutbl: ast::mutability,
 }
 
-fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] {
+fn mk_struct_fields(fields: &[@ast::struct_field]) -> ~[field] {
     do fields.map |field| {
         let (ident, mutbl) = match field.node.kind {
             ast::named_field(ident, mutbl, _) => (ident, mutbl),
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 33eaaaae35b..fc55fd84a87 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -75,9 +75,11 @@ pub enum SyntaxExtension {
     ItemTT(SyntaxExpanderTTItem),
 }
 
+type SyntaxExtensions = HashMap<@~str, SyntaxExtension>;
+
 // A temporary hard-coded map of methods for expanding syntax extension
 // AST nodes into full ASTs
-pub fn syntax_expander_table() -> HashMap<~str, SyntaxExtension> {
+pub fn syntax_expander_table() -> SyntaxExtensions {
     // utility function to simplify creating NormalTT syntax extensions
     fn builtin_normal_tt(f: SyntaxExpanderTTFun) -> SyntaxExtension {
         NormalTT(SyntaxExpanderTT{expander: f, span: None})
@@ -87,74 +89,74 @@ pub fn syntax_expander_table() -> HashMap<~str, SyntaxExtension> {
         ItemTT(SyntaxExpanderTTItem{expander: f, span: None})
     }
     let syntax_expanders = HashMap();
-    syntax_expanders.insert(~"macro_rules",
+    syntax_expanders.insert(@~"macro_rules",
                             builtin_item_tt(
                                 ext::tt::macro_rules::add_new_extension));
-    syntax_expanders.insert(~"fmt",
+    syntax_expanders.insert(@~"fmt",
                             builtin_normal_tt(ext::fmt::expand_syntax_ext));
     syntax_expanders.insert(
-        ~"auto_encode",
+        @~"auto_encode",
         ItemDecorator(ext::auto_encode::expand_auto_encode));
     syntax_expanders.insert(
-        ~"auto_decode",
+        @~"auto_decode",
         ItemDecorator(ext::auto_encode::expand_auto_decode));
-    syntax_expanders.insert(~"env",
+    syntax_expanders.insert(@~"env",
                             builtin_normal_tt(ext::env::expand_syntax_ext));
-    syntax_expanders.insert(~"concat_idents",
+    syntax_expanders.insert(@~"concat_idents",
                             builtin_normal_tt(
                                 ext::concat_idents::expand_syntax_ext));
-    syntax_expanders.insert(~"log_syntax",
+    syntax_expanders.insert(@~"log_syntax",
                             builtin_normal_tt(
                                 ext::log_syntax::expand_syntax_ext));
-    syntax_expanders.insert(~"deriving_eq",
+    syntax_expanders.insert(@~"deriving_eq",
                             ItemDecorator(
                                 ext::deriving::expand_deriving_eq));
-    syntax_expanders.insert(~"deriving_iter_bytes",
+    syntax_expanders.insert(@~"deriving_iter_bytes",
                             ItemDecorator(
                                 ext::deriving::expand_deriving_iter_bytes));
 
     // Quasi-quoting expanders
-    syntax_expanders.insert(~"quote_tokens",
+    syntax_expanders.insert(@~"quote_tokens",
                        builtin_normal_tt(ext::quote::expand_quote_tokens));
-    syntax_expanders.insert(~"quote_expr",
+    syntax_expanders.insert(@~"quote_expr",
                             builtin_normal_tt(ext::quote::expand_quote_expr));
-    syntax_expanders.insert(~"quote_ty",
+    syntax_expanders.insert(@~"quote_ty",
                             builtin_normal_tt(ext::quote::expand_quote_ty));
-    syntax_expanders.insert(~"quote_item",
+    syntax_expanders.insert(@~"quote_item",
                             builtin_normal_tt(ext::quote::expand_quote_item));
-    syntax_expanders.insert(~"quote_pat",
+    syntax_expanders.insert(@~"quote_pat",
                             builtin_normal_tt(ext::quote::expand_quote_pat));
-    syntax_expanders.insert(~"quote_stmt",
+    syntax_expanders.insert(@~"quote_stmt",
                             builtin_normal_tt(ext::quote::expand_quote_stmt));
 
-    syntax_expanders.insert(~"line",
+    syntax_expanders.insert(@~"line",
                             builtin_normal_tt(
                                 ext::source_util::expand_line));
-    syntax_expanders.insert(~"col",
+    syntax_expanders.insert(@~"col",
                             builtin_normal_tt(
                                 ext::source_util::expand_col));
-    syntax_expanders.insert(~"file",
+    syntax_expanders.insert(@~"file",
                             builtin_normal_tt(
                                 ext::source_util::expand_file));
-    syntax_expanders.insert(~"stringify",
+    syntax_expanders.insert(@~"stringify",
                             builtin_normal_tt(
                                 ext::source_util::expand_stringify));
-    syntax_expanders.insert(~"include",
+    syntax_expanders.insert(@~"include",
                             builtin_normal_tt(
                                 ext::source_util::expand_include));
-    syntax_expanders.insert(~"include_str",
+    syntax_expanders.insert(@~"include_str",
                             builtin_normal_tt(
                                 ext::source_util::expand_include_str));
-    syntax_expanders.insert(~"include_bin",
+    syntax_expanders.insert(@~"include_bin",
                             builtin_normal_tt(
                                 ext::source_util::expand_include_bin));
-    syntax_expanders.insert(~"module_path",
+    syntax_expanders.insert(@~"module_path",
                             builtin_normal_tt(
                                 ext::source_util::expand_mod));
-    syntax_expanders.insert(~"proto",
+    syntax_expanders.insert(@~"proto",
                             builtin_item_tt(ext::pipes::expand_proto));
     syntax_expanders.insert(
-        ~"trace_macros",
+        @~"trace_macros",
         builtin_normal_tt(ext::trace_macros::expand_trace_macros));
     return syntax_expanders;
 }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 85821ae6d82..f9a0de6535b 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -13,6 +13,7 @@ use core::prelude::*;
 use ast::{crate, expr_, expr_mac, mac_invoc_tt};
 use ast::{tt_delim, tt_tok, item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi};
 use ast;
+use attr;
 use codemap::{span, ExpandedFrom};
 use ext::base::*;
 use fold::*;
@@ -22,7 +23,7 @@ use core::option;
 use core::vec;
 use std::oldmap::HashMap;
 
-pub fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
+pub fn expand_expr(exts: SyntaxExtensions, cx: ext_ctxt,
                    e: expr_, s: span, fld: ast_fold,
                    orig: fn@(expr_, span, ast_fold) -> (expr_, span))
                 -> (expr_, span) {
@@ -40,7 +41,7 @@ pub fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
                 /* using idents and token::special_idents would make the
                 the macro names be hygienic */
                 let extname = cx.parse_sess().interner.get(pth.idents[0]);
-                match exts.find(extname) {
+                match exts.find(&extname) {
                   None => {
                     cx.span_fatal(pth.span,
                                   fmt!("macro undefined: '%s'", *extname))
@@ -87,7 +88,7 @@ pub fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
 //
 // NB: there is some redundancy between this and expand_item, below, and
 // they might benefit from some amount of semantic and language-UI merger.
-pub fn expand_mod_items(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
+pub fn expand_mod_items(exts: SyntaxExtensions, cx: ext_ctxt,
                         module_: ast::_mod, fld: ast_fold,
                         orig: fn@(ast::_mod, ast_fold) -> ast::_mod)
                      -> ast::_mod {
@@ -99,16 +100,13 @@ pub fn expand_mod_items(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
     // the item into a new set of items.
     let new_items = do vec::flat_map(module_.items) |item| {
         do vec::foldr(item.attrs, ~[*item]) |attr, items| {
-            let mname = match attr.node.value.node {
-              ast::meta_word(ref n) => (*n),
-              ast::meta_name_value(ref n, _) => (*n),
-              ast::meta_list(ref n, _) => (*n)
-            };
+            let mname = attr::get_attr_name(attr);
+
             match exts.find(&mname) {
               None | Some(NormalTT(_)) | Some(ItemTT(*)) => items,
               Some(ItemDecorator(dec_fn)) => {
                   cx.bt_push(ExpandedFrom({call_site: attr.span,
-                                           callie: {name: copy mname,
+                                           callie: {name: /*bad*/ copy *mname,
                                                     span: None}}));
                   let r = dec_fn(cx, attr.span, attr.node.value, items);
                   cx.bt_pop();
@@ -123,7 +121,7 @@ pub fn expand_mod_items(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
 
 
 // When we enter a module, record it, for the sake of `module!`
-pub fn expand_item(exts: HashMap<~str, SyntaxExtension>,
+pub fn expand_item(exts: SyntaxExtensions,
                    cx: ext_ctxt, &&it: @ast::item, fld: ast_fold,
                    orig: fn@(&&v: @ast::item, ast_fold) -> Option<@ast::item>)
                 -> Option<@ast::item> {
@@ -149,7 +147,7 @@ pub fn expand_item(exts: HashMap<~str, SyntaxExtension>,
 
 // Support for item-position macro invocations, exactly the same
 // logic as for expression-position macro invocations.
-pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>,
+pub fn expand_item_mac(exts: SyntaxExtensions,
                        cx: ext_ctxt, &&it: @ast::item,
                        fld: ast_fold) -> Option<@ast::item> {
 
@@ -161,7 +159,7 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>,
     };
 
     let extname = cx.parse_sess().interner.get(pth.idents[0]);
-    let expanded = match exts.find(extname) {
+    let expanded = match exts.find(&extname) {
         None => cx.span_fatal(pth.span,
                               fmt!("macro undefined: '%s!'", *extname)),
 
@@ -200,7 +198,7 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>,
         MRAny(_, item_maker, _) =>
             option::chain(item_maker(), |i| {fld.fold_item(i)}),
         MRDef(ref mdef) => {
-            exts.insert((*mdef).name, (*mdef).ext);
+            exts.insert(@/*bad*/ copy mdef.name, (*mdef).ext);
             None
         }
     };
@@ -208,7 +206,7 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>,
     return maybe_it;
 }
 
-pub fn expand_stmt(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
+pub fn expand_stmt(exts: SyntaxExtensions, cx: ext_ctxt,
                    && s: stmt_, sp: span, fld: ast_fold,
                    orig: fn@(&&s: stmt_, span, ast_fold) -> (stmt_, span))
                 -> (stmt_, span) {
@@ -224,7 +222,7 @@ pub fn expand_stmt(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
 
     assert(vec::len(pth.idents) == 1u);
     let extname = cx.parse_sess().interner.get(pth.idents[0]);
-    let (fully_expanded, sp) = match exts.find(extname) {
+    let (fully_expanded, sp) = match exts.find(&extname) {
         None =>
             cx.span_fatal(pth.span, fmt!("macro undefined: '%s'", *extname)),
 
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 6c461738798..f4d0e57c595 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -228,9 +228,10 @@ pub impl ext_ctxt_ast_builder for ext_ctxt {
         let non_camel_case_attribute = respan(dummy_sp(), ast::attribute_ {
             style: ast::attr_outer,
             value: respan(dummy_sp(),
-                          ast::meta_list(~"allow", ~[
+                          ast::meta_list(@~"allow", ~[
                               @respan(dummy_sp(),
-                                      ast::meta_word(~"non_camel_case_types"))
+                                      ast::meta_word(
+                                         @~"non_camel_case_types"))
                           ])),
             is_sugared_doc: false
         });
diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs
index 4676b5ed393..cc42a0992cb 100644
--- a/src/libsyntax/ext/pipes/check.rs
+++ b/src/libsyntax/ext/pipes/check.rs
@@ -54,27 +54,27 @@ pub impl proto::visitor<(), (), ()> for ext_ctxt {
     fn visit_message(&self, name: ~str, _span: span, _tys: &[@ast::Ty],
                      this: state, next: Option<next_state>) {
         match next {
-          Some(next_state { state: ref next, tys: next_tys }) => {
+          Some(ref next_state) => {
             let proto = this.proto;
-            if !proto.has_state((*next)) {
+            if !proto.has_state(next_state.state) {
                 // This should be a span fatal, but then we need to
                 // track span information.
                 self.span_err(
-                    proto.get_state((*next)).span,
+                    proto.get_state(next_state.state).span,
                     fmt!("message %s steps to undefined state, %s",
-                         name, (*next)));
+                         name, next_state.state));
             }
             else {
-                let next = proto.get_state((*next));
+                let next = proto.get_state(next_state.state);
 
-                if next.ty_params.len() != next_tys.len() {
+                if next.ty_params.len() != next_state.tys.len() {
                     self.span_err(
                         next.span, // use a real span
                         fmt!("message %s target (%s) \
                               needs %u type parameters, but got %u",
                              name, next.name,
                              next.ty_params.len(),
-                             next_tys.len()));
+                             next_state.tys.len()));
                 }
             }
           }
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 77164803caa..48bd8b03297 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -50,16 +50,13 @@ pub impl gen_send for message {
     fn gen_send(&self, cx: ext_ctxt, try: bool) -> @ast::item {
         debug!("pipec: gen_send");
         match *self {
-          message(ref _id, span, tys, this,
-                  Some(next_state {state: ref next, tys: next_tys})) => {
+          message(ref _id, span, ref tys, this, Some(ref next_state)) => {
             debug!("pipec: next state exists");
-            let next = this.proto.get_state((*next));
-            assert next_tys.len() == next.ty_params.len();
+            let next = this.proto.get_state(next_state.state);
+            assert next_state.tys.len() == next.ty_params.len();
             let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str()));
 
-            let args_ast = (arg_names, tys).map(
-                |n, t| cx.arg(*n, *t)
-            );
+            let args_ast = (arg_names, *tys).map(|n, t| cx.arg(*n, *t));
 
             let pipe_ty = cx.ty_path_ast_builder(
                 path(~[this.data_name()], span)
@@ -119,7 +116,7 @@ pub impl gen_send for message {
 
             let mut rty = cx.ty_path_ast_builder(path(~[next.data_name()],
                                                       span)
-                                                 .add_tys(next_tys));
+                                                 .add_tys(next_state.tys));
             if try {
                 rty = cx.ty_option(rty);
             }
@@ -134,13 +131,13 @@ pub impl gen_send for message {
                             cx.expr_block(body))
           }
 
-            message(ref _id, span, tys, this, None) => {
+            message(ref _id, span, ref tys, this, None) => {
                 debug!("pipec: no next state");
                 let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str()));
 
-                let args_ast = (arg_names, tys).map(
-                    |n, t| cx.arg(cx.ident_of(*n), *t)
-                );
+                let args_ast = do (arg_names, *tys).map |n, t| {
+                    cx.arg(cx.ident_of(*n), *t)
+                };
 
                 let args_ast = vec::append(
                     ~[cx.arg(cx.ident_of(~"pipe"),
@@ -219,8 +216,8 @@ pub impl to_type_decls for state {
             let message(name, span, tys, this, next) = *m;
 
             let tys = match next {
-              Some(next_state { state: ref next, tys: next_tys }) => {
-                let next = this.proto.get_state((*next));
+              Some(ref next_state) => {
+                let next = this.proto.get_state((next_state.state));
                 let next_name = cx.str_of(next.data_name());
 
                 let dir = match this.dir {
@@ -232,7 +229,7 @@ pub impl to_type_decls for state {
                                 cx.ty_path_ast_builder(
                                     path(~[cx.ident_of(dir),
                                            cx.ident_of(next_name)], span)
-                                    .add_tys(next_tys)))
+                                    .add_tys(next_state.tys)))
               }
               None => tys
             };
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 3e7a84240e4..dd0dfd8e443 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -59,12 +59,13 @@ pub fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
                                      arg_reader as reader, argument_gram);
 
     // Extract the arguments:
-    let lhses:~[@named_match] = match argument_map.get(&lhs_nm) {
-      @matched_seq(s, _) => s,
-      _ => cx.span_bug(sp, ~"wrong-structured lhs")
+    let lhses = match argument_map.get(&lhs_nm) {
+        @matched_seq(ref s, _) => /* FIXME (#2543) */ copy *s,
+        _ => cx.span_bug(sp, ~"wrong-structured lhs")
     };
-    let rhses:~[@named_match] = match argument_map.get(&rhs_nm) {
-      @matched_seq(s, _) => s,
+
+    let rhses = match argument_map.get(&rhs_nm) {
+      @matched_seq(ref s, _) => /* FIXME (#2543) */ copy *s,
       _ => cx.span_bug(sp, ~"wrong-structured rhs")
     };
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index dc5d7916c7e..dacb6f60e37 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -82,10 +82,10 @@ fn fold_meta_item_(&&mi: @meta_item, fld: ast_fold) -> @meta_item {
         node:
             match mi.node {
                 meta_word(ref id) => meta_word((*id)),
-                meta_list(ref id, mis) => {
-                    let fold_meta_item = |x|fold_meta_item_(x, fld);
-                    meta_list(/* FIXME: (#2543) */ copy (*id),
-                        vec::map(mis, |e| fold_meta_item(*e)))
+                meta_list(ref id, ref mis) => {
+                    let fold_meta_item = |x| fold_meta_item_(x, fld);
+                    meta_list(/* FIXME: (#2543) */ copy *id,
+                              mis.map(|e| fold_meta_item(*e)))
                 }
                 meta_name_value(ref id, s) => {
                     meta_name_value((*id), /* FIXME (#2543) */ copy s)
@@ -213,52 +213,54 @@ fn noop_fold_struct_field(&&sf: @struct_field, fld: ast_fold)
 }
 
 pub fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
-    return match i {
-          item_const(t, e) => item_const(fld.fold_ty(t), fld.fold_expr(e)),
-          item_fn(decl, purity, typms, ref body) => {
-              item_fn(fold_fn_decl(decl, fld),
-                      purity,
-                      fold_ty_params(typms, fld),
-                      fld.fold_block((*body)))
-          }
-          item_mod(m) => item_mod(fld.fold_mod(m)),
-          item_foreign_mod(nm) => item_foreign_mod(fld.fold_foreign_mod(nm)),
-          item_ty(t, typms) => item_ty(fld.fold_ty(t),
-                                       fold_ty_params(typms, fld)),
-          item_enum(ref enum_definition, typms) => {
+    match i {
+        item_const(t, e) => item_const(fld.fold_ty(t), fld.fold_expr(e)),
+        item_fn(ref decl, purity, ref typms, ref body) => {
+            item_fn(fold_fn_decl(/* FIXME (#2543) */ copy *decl, fld),
+                    purity,
+                    fold_ty_params(/* FIXME (#2543) */ copy *typms, fld),
+                    fld.fold_block(*body))
+        }
+        item_mod(m) => item_mod(fld.fold_mod(m)),
+        item_foreign_mod(nm) => item_foreign_mod(fld.fold_foreign_mod(nm)),
+        item_ty(t, typms) => item_ty(fld.fold_ty(t),
+                                     fold_ty_params(typms, fld)),
+        item_enum(ref enum_definition, ref typms) => {
             item_enum(ast::enum_def(ast::enum_def_ {
                 variants: enum_definition.variants.map(
                     |x| fld.fold_variant(*x)),
                 common: enum_definition.common.map(
                     |x| fold_struct_def(*x, fld)),
-            }), fold_ty_params(typms, fld))
-          }
-          item_struct(struct_def, typms) => {
-            let struct_def = fold_struct_def(struct_def, fld);
-              item_struct(struct_def, /* FIXME (#2543) */ copy typms)
-          }
-          item_impl(tps, ifce, ty, ref methods) => {
-              item_impl(fold_ty_params(tps, fld),
-                        ifce.map(|p| fold_trait_ref(*p, fld)),
-                        fld.fold_ty(ty),
-                        vec::map(*methods, |x| fld.fold_method(*x)))
-          }
-          item_trait(tps, traits, ref methods) => {
-              let methods = do (*methods).map |method| {
-                  match *method {
-                      required(*) => copy *method,
-                      provided(method) => provided(fld.fold_method(method))
-                  }
-              };
-            item_trait(fold_ty_params(tps, fld),
-                       vec::map(traits, |p| fold_trait_ref(*p, fld)),
+            }), fold_ty_params(/* FIXME (#2543) */ copy *typms, fld))
+        }
+        item_struct(ref struct_def, ref typms) => {
+            let struct_def = fold_struct_def(
+                /* FIXME (#2543) */ copy *struct_def,
+                fld);
+            item_struct(struct_def, /* FIXME (#2543) */ copy *typms)
+        }
+        item_impl(ref tps, ifce, ty, ref methods) => {
+            item_impl(fold_ty_params(/* FIXME (#2543) */ copy *tps, fld),
+                      ifce.map(|p| fold_trait_ref(*p, fld)),
+                      fld.fold_ty(ty),
+                      methods.map(|x| fld.fold_method(*x)))
+        }
+        item_trait(ref tps, ref traits, ref methods) => {
+            let methods = do methods.map |method| {
+                match *method {
+                    required(*) => copy *method,
+                    provided(method) => provided(fld.fold_method(method))
+                }
+            };
+            item_trait(fold_ty_params(/* FIXME (#2543) */ copy *tps, fld),
+                       traits.map(|p| fold_trait_ref(*p, fld)),
                        methods)
-          }
-      item_mac(ref m) => {
-        // FIXME #2888: we might actually want to do something here.
-        item_mac((*m))
-      }
-        };
+        }
+        item_mac(ref m) => {
+            // FIXME #2888: we might actually want to do something here.
+            item_mac((*m))
+        }
+    }
 }
 
 fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold)
@@ -466,14 +468,14 @@ pub fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
             expr_match(fld.fold_expr(expr),
                      vec::map((*arms), |x| fld.fold_arm(*x)))
           }
-          expr_fn(proto, decl, ref body, _) => {
+          expr_fn(proto, ref decl, ref body, _) => {
             expr_fn(proto,
-                    fold_fn_decl(decl, fld),
+                    fold_fn_decl(/* FIXME (#2543) */ copy *decl, fld),
                     fld.fold_block(*body),
                     @())
           }
-          expr_fn_block(decl, ref body) => {
-            expr_fn_block(fold_fn_decl(decl, fld),
+          expr_fn_block(ref decl, ref body) => {
+            expr_fn_block(fold_fn_decl(/* FIXME (#2543) */ copy *decl, fld),
                           fld.fold_block(*body))
           }
           expr_block(ref blk) => expr_block(fld.fold_block((*blk))),
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index e297e33d825..34ac5c16841 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -126,23 +126,23 @@ impl parser_attr for Parser {
 
     fn parse_meta_item() -> @ast::meta_item {
         let lo = self.span.lo;
-        let name = *self.id_to_str(self.parse_ident());
+        let name = self.id_to_str(self.parse_ident());
         match self.token {
-          token::EQ => {
-            self.bump();
-            let lit = self.parse_lit();
-            let mut hi = self.span.hi;
-            return @spanned(lo, hi, ast::meta_name_value(name, lit));
-          }
-          token::LPAREN => {
-            let inner_items = self.parse_meta_seq();
-            let mut hi = self.span.hi;
-            return @spanned(lo, hi, ast::meta_list(name, inner_items));
-          }
-          _ => {
-            let mut hi = self.span.hi;
-            return @spanned(lo, hi, ast::meta_word(name));
-          }
+            token::EQ => {
+                self.bump();
+                let lit = self.parse_lit();
+                let mut hi = self.span.hi;
+                @spanned(lo, hi, ast::meta_name_value(name, lit))
+            }
+            token::LPAREN => {
+                let inner_items = self.parse_meta_seq();
+                let mut hi = self.span.hi;
+                @spanned(lo, hi, ast::meta_list(name, inner_items))
+            }
+            _ => {
+                let mut hi = self.span.hi;
+                @spanned(lo, hi, ast::meta_word(name))
+            }
         }
     }
 
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index d58d894b6a0..e27784d1f6b 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -46,14 +46,14 @@ impl cmp::Eq for cmnt_style {
 
 pub type cmnt = {style: cmnt_style, lines: ~[~str], pos: BytePos};
 
-pub fn is_doc_comment(s: ~str) -> bool {
+pub fn is_doc_comment(s: &str) -> bool {
     (s.starts_with(~"///") && !is_line_non_doc_comment(s)) ||
     s.starts_with(~"//!") ||
     (s.starts_with(~"/**") && !is_block_non_doc_comment(s)) ||
     s.starts_with(~"/*!")
 }
 
-pub fn doc_comment_style(comment: ~str) -> ast::attr_style {
+pub fn doc_comment_style(comment: &str) -> ast::attr_style {
     assert is_doc_comment(comment);
     if comment.starts_with(~"//!") || comment.starts_with(~"/*!") {
         ast::attr_inner
@@ -62,7 +62,7 @@ pub fn doc_comment_style(comment: ~str) -> ast::attr_style {
     }
 }
 
-pub fn strip_doc_comment_decoration(comment: ~str) -> ~str {
+pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
 
     /// remove whitespace-only lines from the start/end of lines
     fn vertical_trim(lines: ~[~str]) -> ~[~str] {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index e5b3024d3dc..644d6ed5189 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3267,11 +3267,11 @@ pub impl Parser {
         // on the mod, then we'll go and suck in another file and merge
         // its contents
         match ::attr::first_attr_value_str_by_name(outer_attrs, ~"merge") {
-            Some(ref path) => {
+            Some(path) => {
                 let prefix = Path(
                     self.sess.cm.span_to_filename(copy self.span));
                 let prefix = prefix.dir_path();
-                let path = Path((*path));
+                let path = Path(copy *path);
                 let (new_mod_item, new_attrs) = self.eval_src_mod_from_path(
                     prefix, path, ~[], id_span);
 
@@ -3300,7 +3300,7 @@ pub impl Parser {
         let file_path = match ::attr::first_attr_value_str_by_name(
             attrs, ~"path") {
 
-            Some(ref d) => (*d),
+            Some(d) => copy *d,
             None => copy *default_path
         };
         self.mod_path_stack.push(file_path)
@@ -3320,10 +3320,10 @@ pub impl Parser {
         let default_path = self.sess.interner.get(id) + ~".rs";
         let file_path = match ::attr::first_attr_value_str_by_name(
             outer_attrs, ~"path") {
-            Some(ref d) => {
-                let path = Path(*d);
+            Some(d) => {
+                let path = Path(copy *d);
                 if !path.is_absolute {
-                    mod_path.push(*d)
+                    mod_path.push(copy *d)
                 } else {
                     path
                 }
@@ -3357,7 +3357,7 @@ pub impl Parser {
 
         fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
             match ::attr::first_attr_value_str_by_name(attrs, ~"path") {
-                Some(ref d) => (*d),
+                Some(d) => copy *d,
                 None => default
             }
         }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index bdd26fc00a7..f145e433fa7 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -429,7 +429,7 @@ pub fn mk_ident_interner() -> @ident_interner {
                 ];
 
                 let rv = @ident_interner {
-                    interner: interner::mk_prefill(init_vec)
+                    interner: interner::Interner::prefill(init_vec)
                 };
 
                 task::local_data::local_data_set(interner_key!(), @rv);
@@ -443,7 +443,7 @@ pub fn mk_ident_interner() -> @ident_interner {
 /* for when we don't care about the contents; doesn't interact with TLD or
    serialization */
 pub fn mk_fake_ident_interner() -> @ident_interner {
-    @ident_interner { interner: interner::mk::<@~str>() }
+    @ident_interner { interner: interner::Interner::new() }
 }
 
 /**
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index c091c436381..eeba00be704 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -498,9 +498,16 @@ pub fn print_item(s: @ps, &&item: @ast::item) {
         end(s); // end the outer cbox
 
       }
-      ast::item_fn(decl, purity, typarams, ref body) => {
-        print_fn(s, decl, Some(purity), item.ident, typarams, None,
-                 item.vis);
+      ast::item_fn(ref decl, purity, ref typarams, ref body) => {
+        print_fn(
+            s,
+            /* FIXME (#2543) */ copy *decl,
+            Some(purity),
+            item.ident,
+            /* FIXME (#2543) */ copy *typarams,
+            None,
+            item.vis
+        );
         word(s.s, ~" ");
         print_block_with_attrs(s, (*body), item.attrs);
       }
@@ -542,9 +549,15 @@ pub fn print_item(s: @ps, &&item: @ast::item) {
         word(s.s, ~";");
         end(s); // end the outer ibox
       }
-      ast::item_enum(ref enum_definition, params) => {
-        print_enum_def(s, (*enum_definition), params, item.ident,
-                       item.span, item.vis);
+      ast::item_enum(ref enum_definition, ref params) => {
+        print_enum_def(
+            s,
+            *enum_definition,
+            /* FIXME (#2543) */ copy *params,
+            item.ident,
+            item.span,
+            item.vis
+        );
       }
       ast::item_struct(struct_def, tps) => {
           head(s, visibility_qualified(item.vis, ~"struct"));
@@ -580,13 +593,13 @@ pub fn print_item(s: @ps, &&item: @ast::item) {
             bclose(s, item.span);
         }
       }
-      ast::item_trait(tps, traits, ref methods) => {
+      ast::item_trait(ref tps, ref traits, ref methods) => {
         head(s, visibility_qualified(item.vis, ~"trait"));
         print_ident(s, item.ident);
-        print_type_params(s, tps);
-        if vec::len(traits) != 0u {
+        print_type_params(s, /* FIXME (#2543) */ copy *tps);
+        if traits.len() != 0u {
             word(s.s, ~":");
-            for vec::each(traits) |trait_| {
+            for traits.each |trait_| {
                 nbsp(s);
                 print_path(s, trait_.path, false);
             }
@@ -622,7 +635,7 @@ pub fn print_enum_def(s: @ps, enum_definition: ast::enum_def,
         ident == enum_definition.variants[0].node.name;
     if newtype {
         match enum_definition.variants[0].node.kind {
-            ast::tuple_variant_kind(args) if args.len() == 1 => {}
+            ast::tuple_variant_kind(ref args) if args.len() == 1 => {}
             _ => newtype = false
         }
     }
@@ -887,7 +900,7 @@ pub fn print_attribute(s: @ps, attr: ast::attribute) {
     if attr.node.is_sugared_doc {
         let meta = attr::attr_meta(attr);
         let comment = attr::get_meta_item_value_str(meta).get();
-        word(s.s, comment);
+        word(s.s, *comment);
     } else {
         word(s.s, ~"#[");
         print_meta_item(s, @attr.node.value);
@@ -1331,24 +1344,24 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) {
         }
         bclose_(s, expr.span, match_indent_unit);
       }
-      ast::expr_fn(sigil, decl, ref body, _) => {
+      ast::expr_fn(sigil, ref decl, ref body, _) => {
         // containing cbox, will be closed by print-block at }
         cbox(s, indent_unit);
         // head-box, will be closed by print-block at start
         ibox(s, 0u);
         print_fn_header_info(s, None, None, ast::Many,
                              Some(sigil), ast::inherited);
-        print_fn_args_and_ret(s, decl, None);
+        print_fn_args_and_ret(s, /* FIXME (#2543) */ copy *decl, None);
         space(s.s);
         print_block(s, (*body));
       }
-      ast::expr_fn_block(decl, ref body) => {
+      ast::expr_fn_block(ref decl, ref body) => {
         // in do/for blocks we don't want to show an empty
         // argument list, but at this point we don't know which
         // we are inside.
         //
         // if !decl.inputs.is_empty() {
-        print_fn_block_args(s, decl);
+        print_fn_block_args(s, /* FIXME (#2543) */ copy *decl);
         space(s.s);
         // }
         assert (*body).node.stmts.is_empty();
@@ -1812,16 +1825,21 @@ pub fn print_type_params(s: @ps, &&params: ~[ast::ty_param]) {
 pub fn print_meta_item(s: @ps, &&item: @ast::meta_item) {
     ibox(s, indent_unit);
     match item.node {
-      ast::meta_word(ref name) => word(s.s, (*name)),
-      ast::meta_name_value(ref name, value) => {
-        word_space(s, (*name));
+      ast::meta_word(name) => word(s.s, *name),
+      ast::meta_name_value(name, value) => {
+        word_space(s, *name);
         word_space(s, ~"=");
         print_literal(s, @value);
       }
-      ast::meta_list(ref name, items) => {
-        word(s.s, (*name));
+      ast::meta_list(name, ref items) => {
+        word(s.s, *name);
         popen(s);
-        commasep(s, consistent, items, print_meta_item);
+        commasep(
+            s,
+            consistent,
+            /* FIXME (#2543) */ copy *items,
+            print_meta_item
+        );
         pclose(s);
       }
     }
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 657e6ee59fa..dcb3261169b 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -14,72 +14,66 @@
 
 use core::prelude::*;
 
-use core::dvec::DVec;
-use std::oldmap::HashMap;
-use std::oldmap;
+use hashmap::linear::LinearMap;
+use dvec::DVec;
 
-pub type hash_interner<T> = {map: HashMap<T, uint>, vect: DVec<T>};
-
-pub fn mk<T:Eq IterBytes Hash Const Copy>() -> Interner<T> {
-    let m = oldmap::HashMap::<T, uint>();
-    let hi: hash_interner<T> =
-        {map: m, vect: DVec()};
-    ((hi) as Interner::<T>)
-}
-
-pub fn mk_prefill<T:Eq IterBytes Hash Const Copy>(init: &[T]) -> Interner<T> {
-    let rv = mk();
-    for init.each() |v| { rv.intern(*v); }
-    return rv;
+pub struct Interner<T> {
+    priv mut map: LinearMap<T, uint>,
+    priv vect: DVec<T>,
 }
 
+// when traits can extend traits, we should extend index<uint,T> to get []
+pub impl<T: Eq IterBytes Hash Const Copy> Interner<T> {
+    static fn new() -> Interner<T> {
+        Interner {
+            map: LinearMap::new(),
+            vect: DVec(),
+        }
+    }
 
-/* when traits can extend traits, we should extend index<uint,T> to get [] */
-pub trait Interner<T:Eq IterBytes Hash Const Copy> {
-    fn intern(T) -> uint;
-    fn gensym(T) -> uint;
-    pure fn get(uint) -> T;
-    fn len() -> uint;
-}
+    static fn prefill(init: &[T]) -> Interner<T> {
+        let rv = Interner::new();
+        for init.each() |v| { rv.intern(*v); }
+        rv
+    }
 
-pub impl<T:Eq IterBytes Hash Const Copy> Interner<T> for hash_interner<T> {
-    fn intern(val: T) -> uint {
+    fn intern(&self, val: T) -> uint {
         match self.map.find(&val) {
-          Some(idx) => return idx,
-          None => {
-            let new_idx = self.vect.len();
-            self.map.insert(val, new_idx);
-            self.vect.push(val);
-            return new_idx;
-          }
+            Some(&idx) => return idx,
+            None => (),
         }
+
+        let new_idx = self.vect.len();
+        self.map.insert(val, new_idx);
+        self.vect.push(val);
+        new_idx
     }
-    fn gensym(val: T) -> uint {
+
+    fn gensym(&self, val: T) -> uint {
         let new_idx = self.vect.len();
         // leave out of .map to avoid colliding
         self.vect.push(val);
-        return new_idx;
+        new_idx
     }
 
     // this isn't "pure" in the traditional sense, because it can go from
     // failing to returning a value as items are interned. But for typestate,
     // where we first check a pred and then rely on it, ceasing to fail is ok.
-    pure fn get(idx: uint) -> T { self.vect.get_elt(idx) }
+    pure fn get(&self, idx: uint) -> T { self.vect.get_elt(idx) }
 
-    fn len() -> uint { return self.vect.len(); }
+    fn len(&self) -> uint { self.vect.len() }
 }
 
-
 #[test]
 #[should_fail]
 pub fn i1 () {
-    let i : Interner<@~str> = mk();
+    let i : Interner<@~str> = Interner::new();
     i.get(13);
 }
 
 #[test]
 pub fn i2 () {
-    let i : Interner<@~str> = mk();
+    let i : Interner<@~str> = Interner::new();
     // first one is zero:
     assert i.intern (@~"dog") == 0;
     // re-use gets the same entry:
@@ -104,7 +98,7 @@ pub fn i2 () {
 
 #[test]
 pub fn i3 () {
-    let i : Interner<@~str> = mk_prefill([@~"Alan",@~"Bob",@~"Carol"]);
+    let i : Interner<@~str> = Interner::prefill([@~"Alan",@~"Bob",@~"Carol"]);
     assert i.get(0) == @~"Alan";
     assert i.get(1) == @~"Bob";
     assert i.get(2) == @~"Carol";
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 37b96e05653..3701607ffc1 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -137,11 +137,20 @@ pub fn visit_item<E>(i: @item, e: E, v: vt<E>) {
         (v.visit_ty)(t, e, v);
         (v.visit_expr)(ex, e, v);
       }
-      item_fn(decl, purity, tp, ref body) => {
-        (v.visit_fn)(fk_item_fn(/* FIXME (#2543) */ copy i.ident,
-                              /* FIXME (#2543) */ copy tp,
-                              purity), decl, (*body),
-                   i.span, i.id, e, v);
+      item_fn(ref decl, purity, ref tp, ref body) => {
+        (v.visit_fn)(
+            fk_item_fn(
+                /* FIXME (#2543) */ copy i.ident,
+                /* FIXME (#2543) */ copy *tp,
+                purity
+            ),
+            /* FIXME (#2543) */ copy *decl,
+            (*body),
+            i.span,
+            i.id,
+            e,
+            v
+        );
       }
       item_mod(m) => (v.visit_mod)(m, i.span, i.id, e, v),
       item_foreign_mod(nm) => {
@@ -152,9 +161,14 @@ pub fn visit_item<E>(i: @item, e: E, v: vt<E>) {
         (v.visit_ty)(t, e, v);
         (v.visit_ty_params)(tps, e, v);
       }
-      item_enum(ref enum_definition, tps) => {
-        (v.visit_ty_params)(tps, e, v);
-        visit_enum_def((*enum_definition), tps, e, v);
+      item_enum(ref enum_definition, ref tps) => {
+        (v.visit_ty_params)(/* FIXME (#2543) */ copy *tps, e, v);
+        visit_enum_def(
+            *enum_definition,
+            /* FIXME (#2543) */ copy *tps,
+            e,
+            v
+        );
       }
       item_impl(tps, traits, ty, methods) => {
         (v.visit_ty_params)(tps, e, v);
@@ -170,8 +184,8 @@ pub fn visit_item<E>(i: @item, e: E, v: vt<E>) {
         (v.visit_ty_params)(tps, e, v);
         (v.visit_struct_def)(struct_def, i.ident, tps, i.id, e, v);
       }
-      item_trait(tps, traits, ref methods) => {
-        (v.visit_ty_params)(tps, e, v);
+      item_trait(ref tps, ref traits, ref methods) => {
+        (v.visit_ty_params)(/* FIXME (#2543) */ copy *tps, e, v);
         for traits.each |p| { visit_path(p.path, e, v); }
         for (*methods).each |m| {
             (v.visit_trait_method)(*m, e, v);
@@ -460,13 +474,27 @@ pub fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
         (v.visit_expr)(x, e, v);
         for (*arms).each |a| { (v.visit_arm)(*a, e, v); }
       }
-      expr_fn(proto, decl, ref body, _) => {
-        (v.visit_fn)(fk_anon(proto), decl, (*body),
-                     ex.span, ex.id, e, v);
-      }
-      expr_fn_block(decl, ref body) => {
-        (v.visit_fn)(fk_fn_block, decl, (*body),
-                     ex.span, ex.id, e, v);
+      expr_fn(proto, ref decl, ref body, _) => {
+        (v.visit_fn)(
+            fk_anon(proto),
+            /* FIXME (#2543) */ copy *decl,
+            *body,
+            ex.span,
+            ex.id,
+            e,
+            v
+        );
+      }
+      expr_fn_block(ref decl, ref body) => {
+        (v.visit_fn)(
+            fk_fn_block,
+            /* FIXME (#2543) */ copy *decl,
+            *body,
+            ex.span,
+            ex.id,
+            e,
+            v
+        );
       }
       expr_block(ref b) => (v.visit_block)((*b), e, v),
       expr_assign(a, b) => {