about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-06-10 00:49:59 -0700
committerBrian Anderson <banderson@mozilla.com>2012-06-13 11:30:45 -0700
commitce750a7dbcd2dc68db6de89956b1de3ecf9f2d0a (patch)
tree55c2ee5be0986c2489879022d4788d6c3ac2c964 /src/libsyntax
parentbdd20000665a35e14b4ec2c54f893fc80fe451ef (diff)
downloadrust-ce750a7dbcd2dc68db6de89956b1de3ecf9f2d0a.tar.gz
rust-ce750a7dbcd2dc68db6de89956b1de3ecf9f2d0a.zip
Box AST idents
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/ast_map.rs26
-rw-r--r--src/libsyntax/ast_util.rs7
-rw-r--r--src/libsyntax/attr.rs50
-rw-r--r--src/libsyntax/ext/auto_serialize.rs75
-rw-r--r--src/libsyntax/ext/base.rs4
-rw-r--r--src/libsyntax/ext/build.rs2
-rw-r--r--src/libsyntax/ext/concat_idents.rs6
-rw-r--r--src/libsyntax/ext/env.rs4
-rw-r--r--src/libsyntax/ext/expand.rs12
-rw-r--r--src/libsyntax/ext/fmt.rs23
-rw-r--r--src/libsyntax/ext/qquote.rs34
-rw-r--r--src/libsyntax/ext/simplext.rs14
-rw-r--r--src/libsyntax/ext/source_util.rs9
-rw-r--r--src/libsyntax/parse/common.rs6
-rw-r--r--src/libsyntax/parse/eval.rs16
-rw-r--r--src/libsyntax/parse/parser.rs28
-rw-r--r--src/libsyntax/print/pprust.rs72
-rw-r--r--src/libsyntax/visit.rs4
19 files changed, 204 insertions, 194 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index ad1501dd8b0..5381a9f345d 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -30,7 +30,7 @@ fn deserialize_span<D>(_d: D) -> span {
 type spanned<T> = {node: T, span: span};
 
 #[auto_serialize]
-type ident = str;
+type ident = @str;
 
 // Functions may or may not have names.
 #[auto_serialize]
@@ -399,11 +399,11 @@ type lit = spanned<lit_>;
 
 #[auto_serialize]
 enum lit_ {
-    lit_str(str),
+    lit_str(@str),
     lit_int(i64, int_ty),
     lit_uint(u64, uint_ty),
     lit_int_unsuffixed(i64, int_ty),
-    lit_float(str, float_ty),
+    lit_float(@str, float_ty),
     lit_nil,
     lit_bool(bool),
 }
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 10397e795ab..98a3a8e7bcc 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -6,14 +6,14 @@ import ast_util::path_to_ident;
 import ast_util::inlined_item_methods;
 import diagnostic::span_handler;
 
-enum path_elt { path_mod(str), path_name(str) }
+enum path_elt { path_mod(ident), path_name(ident) }
 type path = [path_elt];
 
 fn path_to_str_with_sep(p: path, sep: str) -> str {
     let strs = vec::map(p) {|e|
         alt e {
-          path_mod(s) { /* FIXME: bad */ copy s }
-          path_name(s) { /* FIXME: bad */ copy s }
+          path_mod(s) { /* FIXME: bad */ copy *s }
+          path_name(s) { /* FIXME: bad */ copy *s }
         }
     };
     str::connect(strs, sep)
@@ -21,9 +21,9 @@ fn path_to_str_with_sep(p: path, sep: str) -> str {
 
 fn path_ident_to_str(p: path, i: ident) -> str {
     if vec::is_empty(p) {
-        /* FIXME: bad */ copy i
+        /* FIXME: bad */ copy *i
     } else {
-        #fmt["%s::%s", path_to_str(p), i]
+        #fmt["%s::%s", path_to_str(p), *i]
     }
 }
 
@@ -59,7 +59,7 @@ type ctx = {map: map, mut path: path,
             mut local_id: uint, diag: span_handler};
 type vt = visit::vt<ctx>;
 
-fn extend(cx: ctx, +elt: str) -> @path {
+fn extend(cx: ctx, +elt: ident) -> @path {
     @(cx.path + [path_name(elt)])
 }
 
@@ -192,7 +192,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
       item_impl(_, _, _, _, ms) {
         let impl_did = ast_util::local_def(i.id);
         for ms.each {|m|
-            map_method(impl_did, extend(cx, /* FIXME: bad */ copy i.ident), m,
+            map_method(impl_did, extend(cx, i.ident), m,
                        cx);
         }
       }
@@ -208,7 +208,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
         for vs.each {|v|
             cx.map.insert(v.node.id, node_variant(
                 /* FIXME: bad */ copy v, i,
-                extend(cx, /* FIXME: bad */ copy i.ident)));
+                extend(cx, i.ident)));
         }
       }
       item_native_mod(nm) {
@@ -229,7 +229,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
           vec::iter(ifces) {|p| cx.map.insert(p.id,
                                   node_item(i, item_path)); };
           let d_id = ast_util::local_def(i.id);
-          let p = extend(cx, /* FIXME: bad */ copy i.ident);
+          let p = extend(cx, i.ident);
            // only need to handle methods
           vec::iter(ms) {|m| map_method(d_id, p, m, cx); }
       }
@@ -237,9 +237,9 @@ fn map_item(i: @item, cx: ctx, v: vt) {
     }
     alt i.node {
       item_mod(_) | item_native_mod(_) {
-        cx.path += [path_mod(/* FIXME: bad */ copy i.ident)];
+        cx.path += [path_mod(i.ident)];
       }
-      _ { cx.path += [path_name(/* FIXME: bad */ copy i.ident)]; }
+      _ { cx.path += [path_name(i.ident)]; }
     }
     visit::visit_item(i, cx, v);
     vec::pop(cx.path);
@@ -281,11 +281,11 @@ fn node_id_to_str(map: map, id: node_id) -> str {
       }
       some(node_method(m, impl_did, path)) {
         #fmt["method %s in %s (id=%?)",
-             m.ident, path_to_str(*path), id]
+             *m.ident, path_to_str(*path), id]
       }
       some(node_variant(variant, def_id, path)) {
         #fmt["variant %s in %s (id=%?)",
-             variant.node.name, path_to_str(*path), id]
+             *variant.node.name, path_to_str(*path), id]
       }
       some(node_expr(expr)) {
         #fmt["expr %s (id=%?)",
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 9eee9a33af8..d4efdb4bb0d 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -23,7 +23,10 @@ pure fn dummy_sp() -> span { ret mk_sp(0u, 0u); }
 
 pure fn path_name(p: @path) -> str { path_name_i(p.idents) }
 
-pure fn path_name_i(idents: [ident]) -> str { str::connect(idents, "::") }
+pure fn path_name_i(idents: [ident]) -> str {
+    // FIXME: Bad copies
+    str::connect(idents.map({|i|*i}), "::")
+}
 
 pure fn path_to_ident(p: @path) -> ident { vec::last(p.idents) }
 
@@ -380,7 +383,7 @@ fn dtor_dec() -> fn_decl {
     let nil_t = @{id: 0, node: ty_nil, span: dummy_sp()};
     // dtor has one argument, of type ()
     {inputs: [{mode: ast::expl(ast::by_ref),
-               ty: nil_t, ident: "_", id: 0}],
+               ty: nil_t, ident: @"_", id: 0}],
      output: nil_t, purity: impure_fn, cf: return_val, constraints: []}
 }
 
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index af780bc5e38..9138fed69c8 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -47,7 +47,7 @@ export require_unique_names;
 /* Constructors */
 
 fn mk_name_value_item_str(+name: ast::ident, +value: str) -> @ast::meta_item {
-    let value_lit = dummy_spanned(ast::lit_str(value));
+    let value_lit = dummy_spanned(ast::lit_str(@value));
     ret mk_name_value_item(name, value_lit);
 }
 
@@ -100,12 +100,12 @@ fn get_meta_item_name(meta: @ast::meta_item) -> ast::ident {
 Gets the string value if the meta_item is a meta_name_value variant
 containing a string, otherwise none
 "]
-fn get_meta_item_value_str(meta: @ast::meta_item) -> option<str> {
+fn get_meta_item_value_str(meta: @ast::meta_item) -> option<@str> {
     alt meta.node {
       ast::meta_name_value(_, v) {
         alt v.node {
             ast::lit_str(s) {
-                option::some(/* FIXME bad */ copy s)
+                option::some(s)
             }
             _ {
                 option::none
@@ -130,11 +130,11 @@ a tuple containing the name and string value, otherwise `none`
 "]
 fn get_name_value_str_pair(
     item: @ast::meta_item
-) -> option<(str, str)> {
+) -> option<(ast::ident, @str)> {
     alt attr::get_meta_item_value_str(item) {
       some(value) {
         let name = attr::get_meta_item_name(item);
-        some((name, /* FIXME bad */ copy value))
+        some((name, value))
       }
       none { none }
     }
@@ -146,11 +146,11 @@ fn get_name_value_str_pair(
 #[doc = "
 Search a list of attributes and return only those with a specific name
 "]
-fn find_attrs_by_name(attrs: [ast::attribute], +name: ast::ident) ->
+fn find_attrs_by_name(attrs: [ast::attribute], +name: str) ->
    [ast::attribute] {
     let filter = (
         fn@(a: ast::attribute) -> option<ast::attribute> {
-            if get_attr_name(a) == name {
+            if *get_attr_name(a) == name {
                 option::some(a)
             } else { option::none }
         }
@@ -161,10 +161,10 @@ fn find_attrs_by_name(attrs: [ast::attribute], +name: ast::ident) ->
 #[doc = "
 Searcha list of meta items and return only those with a specific name
 "]
-fn find_meta_items_by_name(metas: [@ast::meta_item], +name: ast::ident) ->
+fn find_meta_items_by_name(metas: [@ast::meta_item], +name: str) ->
    [@ast::meta_item] {
     let filter = fn@(&&m: @ast::meta_item) -> option<@ast::meta_item> {
-        if get_meta_item_name(m) == name {
+        if *get_meta_item_name(m) == name {
             option::some(m)
         } else { option::none }
     };
@@ -209,17 +209,17 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool {
         }
 }
 
-fn contains_name(metas: [@ast::meta_item], +name: ast::ident) -> bool {
+fn contains_name(metas: [@ast::meta_item], +name: str) -> bool {
     let matches = find_meta_items_by_name(metas, name);
     ret vec::len(matches) > 0u;
 }
 
-fn attrs_contains_name(attrs: [ast::attribute], +name: ast::ident) -> bool {
+fn attrs_contains_name(attrs: [ast::attribute], +name: str) -> bool {
     vec::is_not_empty(find_attrs_by_name(attrs, name))
 }
 
-fn first_attr_value_str_by_name(attrs: [ast::attribute], +name: ast::ident)
-    -> option<str> {
+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 {
         ret get_meta_item_value_str(attr_meta(mattrs[0]));
@@ -238,11 +238,11 @@ fn last_meta_item_by_name(
 fn last_meta_item_value_str_by_name(
     items: [@ast::meta_item],
     +name: str
-) -> option<str> {
+) -> option<@str> {
     alt last_meta_item_by_name(items, name) {
       some(item) {
         alt attr::get_meta_item_value_str(item) {
-          some(value) { some(/* FIXME bad */ copy value) }
+          some(value) { some(value) }
           none { none }
         }
       }
@@ -285,7 +285,7 @@ fn sort_meta_items(+items: [@ast::meta_item]) -> [@ast::meta_item] {
     ret vec::from_mut(v);
 }
 
-fn remove_meta_items_by_name(items: [@ast::meta_item], name: str) ->
+fn remove_meta_items_by_name(items: [@ast::meta_item], name: ast::ident) ->
    [@ast::meta_item] {
 
     ret vec::filter_map(items, {
@@ -326,17 +326,17 @@ fn native_abi(attrs: [ast::attribute]) -> either<str, ast::native_abi> {
       option::none {
         either::right(ast::native_abi_cdecl)
       }
-      option::some("rust-intrinsic") {
+      option::some(@"rust-intrinsic") {
         either::right(ast::native_abi_rust_intrinsic)
       }
-      option::some("cdecl") {
+      option::some(@"cdecl") {
         either::right(ast::native_abi_cdecl)
       }
-      option::some("stdcall") {
+      option::some(@"stdcall") {
         either::right(ast::native_abi_stdcall)
       }
       option::some(t) {
-        either::left("unsupported abi: " + t)
+        either::left("unsupported abi: " + *t)
       }
     };
 }
@@ -352,8 +352,8 @@ fn find_inline_attr(attrs: [ast::attribute]) -> inline_attr {
     // TODO---validate the usage of #[inline] and #[inline(always)]
     vec::foldl(ia_none, attrs) {|ia,attr|
         alt 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 {
@@ -373,11 +373,11 @@ fn require_unique_names(diagnostic: span_handler,
         let name = get_meta_item_name(meta);
 
         // FIXME: How do I silence the warnings? --pcw
-        if map.contains_key(name) {
+        if map.contains_key(*name) {
             diagnostic.span_fatal(meta.span,
-                                  #fmt["duplicate meta item `%s`", name]);
+                                  #fmt["duplicate meta item `%s`", *name]);
         }
-        map.insert(name, ());
+        map.insert(*name, ());
     }
 }
 
diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs
index dc632d6b6ac..888ff7d4ef2 100644
--- a/src/libsyntax/ext/auto_serialize.rs
+++ b/src/libsyntax/ext/auto_serialize.rs
@@ -92,7 +92,7 @@ fn expand(cx: ext_ctxt,
           _mitem: ast::meta_item,
           in_items: [@ast::item]) -> [@ast::item] {
     fn not_auto_serialize(a: ast::attribute) -> bool {
-        attr::get_attr_name(a) != "auto_serialize"
+        attr::get_attr_name(a) != @"auto_serialize"
     }
 
     fn filter_attrs(item: @ast::item) -> @ast::item {
@@ -126,18 +126,19 @@ impl helpers for ext_ctxt {
                    helper_name: str) -> @ast::path {
         let head = vec::init(base_path.idents);
         let tail = vec::last(base_path.idents);
-        self.path(base_path.span, head + [helper_name + "_" + tail])
+        self.path(base_path.span, head + [@(helper_name + "_" + *tail)])
     }
 
-    fn path(span: span, strs: [str]) -> @ast::path {
+    fn path(span: span, strs: [ast::ident]) -> @ast::path {
         @{span: span, global: false, idents: strs, rp: none, types: []}
     }
 
-    fn path_tps(span: span, strs: [str], tps: [@ast::ty]) -> @ast::path {
+    fn path_tps(span: span, strs: [ast::ident],
+                tps: [@ast::ty]) -> @ast::path {
         @{span: span, global: false, idents: strs, rp: none, types: tps}
     }
 
-    fn ty_path(span: span, strs: [str], tps: [@ast::ty]) -> @ast::ty {
+    fn ty_path(span: span, strs: [ast::ident], tps: [@ast::ty]) -> @ast::ty {
         @{id: self.next_id(),
           node: ast::ty_path(self.path_tps(span, strs, tps), self.next_id()),
           span: span}
@@ -149,7 +150,7 @@ impl helpers for ext_ctxt {
         let args = vec::map(input_tys) {|ty|
             {mode: ast::expl(ast::by_ref),
              ty: ty,
-             ident: "",
+             ident: @"",
              id: self.next_id()}
         };
 
@@ -170,7 +171,7 @@ impl helpers for ext_ctxt {
         @{id: self.next_id(), node: node, span: span}
     }
 
-    fn var_ref(span: span, name: str) -> @ast::expr {
+    fn var_ref(span: span, name: ast::ident) -> @ast::expr {
         self.expr(span, ast::expr_path(self.path(span, [name])))
     }
 
@@ -192,7 +193,7 @@ impl helpers for ext_ctxt {
          span: expr.span}
     }
 
-    fn binder_pat(span: span, nm: str) -> @ast::pat {
+    fn binder_pat(span: span, nm: ast::ident) -> @ast::pat {
         let path = @{span: span, global: false, idents: [nm],
                      rp: none, types: []};
         @{id: self.next_id(),
@@ -212,7 +213,7 @@ impl helpers for ext_ctxt {
                 ast::expr_alt(v, arms, ast::alt_exhaustive)))
     }
 
-    fn lit_str(span: span, s: str) -> @ast::expr {
+    fn lit_str(span: span, s: @str) -> @ast::expr {
         self.expr(
             span,
             ast::expr_lit(
@@ -310,7 +311,7 @@ fn ser_variant(cx: ext_ctxt,
                bodyfn: fn(-@ast::expr, ast::blk) -> @ast::expr,
                argfn: fn(-@ast::expr, uint, ast::blk) -> @ast::expr)
     -> ast::arm {
-    let vnames = vec::from_fn(vec::len(tys)) {|i| #fmt["__v%u", i]};
+    let vnames = vec::from_fn(vec::len(tys)) {|i| @#fmt["__v%u", i]};
     let pats = vec::from_fn(vec::len(tys)) {|i|
         cx.binder_pat(tys[i].span, vnames[i])
     };
@@ -428,7 +429,7 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
             vec::is_empty(path.types) {
             let ident = path.idents[0];
 
-            alt tps.find(ident) {
+            alt tps.find(*ident) {
               some(f) { f(v) }
               none { ser_path(cx, tps, path, s, v) }
             }
@@ -474,7 +475,7 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
     }
 }
 
-fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
+fn mk_ser_fn(cx: ext_ctxt, span: span, name: ast::ident, tps: [ast::ty_param],
              f: fn(ext_ctxt, ser_tps_map,
                    -@ast::expr, -@ast::expr) -> [@ast::stmt])
     -> @ast::item {
@@ -489,7 +490,7 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
              ty: cx.ty_fn(span,
                           [cx.ty_path(span, [tp.ident], [])],
                           cx.ty_nil(span)),
-             ident: "__s" + tp.ident,
+             ident: @("__s" + *tp.ident),
              id: cx.next_id()}});
 
     #debug["tp_inputs = %?", tp_inputs];
@@ -497,12 +498,12 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
 
     let ser_inputs: [ast::arg] =
         [{mode: ast::expl(ast::by_ref),
-          ty: cx.ty_path(span, ["__S"], []),
-          ident: "__s",
+          ty: cx.ty_path(span, [@"__S"], []),
+          ident: @"__s",
           id: cx.next_id()},
          {mode: ast::expl(ast::by_ref),
           ty: v_ty,
-          ident: "__v",
+          ident: @"__v",
           id: cx.next_id()}]
         + tp_inputs;
 
@@ -510,21 +511,21 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
     vec::iter2(tps, tp_inputs) {|tp, arg|
         let arg_ident = arg.ident;
         tps_map.insert(
-            tp.ident,
+            *tp.ident,
             fn@(v: @ast::expr) -> [@ast::stmt] {
                 let f = cx.var_ref(span, arg_ident);
-                #debug["serializing type arg %s", arg_ident];
+                #debug["serializing type arg %s", *arg_ident];
                 [#ast(stmt){$(f)($(v));}]
             });
     }
 
     let ser_bnds = @[
         ast::bound_iface(cx.ty_path(span,
-                                    ["std", "serialization", "serializer"],
+                                    [@"std", @"serialization", @"serializer"],
                                     []))];
 
     let ser_tps: [ast::ty_param] =
-        [{ident: "__S",
+        [{ident: @"__S",
           id: cx.next_id(),
           bounds: ser_bnds}] +
         vec::map(tps) {|tp| cx.clone_ty_param(tp) };
@@ -536,7 +537,7 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
     let ser_blk = cx.blk(span,
                          f(cx, tps_map, #ast{ __s }, #ast{ __v }));
 
-    @{ident: "serialize_" + name,
+    @{ident: @("serialize_" + *name),
       attrs: [],
       id: cx.next_id(),
       node: ast::item_fn({inputs: ser_inputs,
@@ -651,7 +652,7 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map,
             vec::is_empty(path.types) {
             let ident = path.idents[0];
 
-            alt tps.find(ident) {
+            alt tps.find(*ident) {
               some(f) { f() }
               none { deser_path(cx, tps, path, d) }
             }
@@ -683,7 +684,8 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map,
     }
 }
 
-fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
+fn mk_deser_fn(cx: ext_ctxt, span: span,
+               name: ast::ident, tps: [ast::ty_param],
                f: fn(ext_ctxt, deser_tps_map, -@ast::expr) -> @ast::expr)
     -> @ast::item {
     let ext_cx = cx; // required for #ast
@@ -697,15 +699,15 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
              ty: cx.ty_fn(span,
                           [],
                           cx.ty_path(span, [tp.ident], [])),
-             ident: "__d" + tp.ident,
+             ident: @("__d" + *tp.ident),
              id: cx.next_id()}});
 
     #debug["tp_inputs = %?", tp_inputs];
 
     let deser_inputs: [ast::arg] =
         [{mode: ast::expl(ast::by_ref),
-          ty: cx.ty_path(span, ["__D"], []),
-          ident: "__d",
+          ty: cx.ty_path(span, [@"__D"], []),
+          ident: @"__d",
           id: cx.next_id()}]
         + tp_inputs;
 
@@ -713,7 +715,7 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
     vec::iter2(tps, tp_inputs) {|tp, arg|
         let arg_ident = arg.ident;
         tps_map.insert(
-            tp.ident,
+            *tp.ident,
             fn@() -> @ast::expr {
                 let f = cx.var_ref(span, arg_ident);
                 #ast{ $(f)() }
@@ -721,12 +723,13 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
     }
 
     let deser_bnds = @[
-        ast::bound_iface(cx.ty_path(span,
-                                    ["std", "serialization", "deserializer"],
-                                    []))];
+        ast::bound_iface(cx.ty_path(
+            span,
+            [@"std", @"serialization", @"deserializer"],
+            []))];
 
     let deser_tps: [ast::ty_param] =
-        [{ident: "__D",
+        [{ident: @"__D",
           id: cx.next_id(),
           bounds: deser_bnds}] + vec::map(tps) {|tp|
         let cloned = cx.clone_ty_param(tp);
@@ -735,7 +738,7 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
 
     let deser_blk = cx.expr_blk(f(cx, tps_map, #ast(expr){__d}));
 
-    @{ident: "deserialize_" + name,
+    @{ident: @("deserialize_" + *name),
       attrs: [],
       id: cx.next_id(),
       node: ast::item_fn({inputs: deser_inputs,
@@ -749,7 +752,7 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param],
       span: span}
 }
 
-fn ty_fns(cx: ext_ctxt, name: str, ty: @ast::ty, tps: [ast::ty_param])
+fn ty_fns(cx: ext_ctxt, name: ast::ident, ty: @ast::ty, tps: [ast::ty_param])
     -> [@ast::item] {
 
     let span = ty.span;
@@ -759,7 +762,7 @@ fn ty_fns(cx: ext_ctxt, name: str, ty: @ast::ty, tps: [ast::ty_param])
     ]
 }
 
-fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: str,
+fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: ast::ident,
             e_span: span, variants: [ast::variant],
             -s: @ast::expr, -v: @ast::expr) -> [@ast::stmt] {
     let ext_cx = cx;
@@ -808,7 +811,7 @@ fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: str,
     [#ast(stmt){ $(s).emit_enum($(e_name), $(lam)) }]
 }
 
-fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: str,
+fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: ast::ident,
               e_span: span, variants: [ast::variant],
               -d: @ast::expr) -> @ast::expr {
     let ext_cx = cx;
@@ -852,7 +855,7 @@ fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: str,
     #ast{ $(d).read_enum($(e_name), $(read_lambda)) }
 }
 
-fn enum_fns(cx: ext_ctxt, e_name: str, e_span: span,
+fn enum_fns(cx: ext_ctxt, e_name: ast::ident, e_span: span,
                variants: [ast::variant], tps: [ast::ty_param])
     -> [@ast::item] {
     [
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 29e20212d66..e39f9745249 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -9,7 +9,7 @@ type syntax_expander_ =
 type syntax_expander = {
     expander: syntax_expander_,
     span: option<span>};
-type macro_def = {ident: str, ext: syntax_extension};
+type macro_def = {ident: ast::ident, ext: syntax_extension};
 type macro_definer =
     fn@(ext_ctxt, span, ast::mac_arg, ast::mac_body) -> macro_def;
 type item_decorator =
@@ -150,7 +150,7 @@ fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, error: str) -> str {
     alt expr.node {
       ast::expr_lit(l) {
         alt l.node {
-          ast::lit_str(s) { ret s; }
+          ast::lit_str(s) { ret *s; }
           _ { cx.span_fatal(l.span, error); }
         }
       }
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 516deb1e793..69f7f2b69cd 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -6,7 +6,7 @@ fn mk_lit(cx: ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr {
     ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp};
 }
 fn mk_str(cx: ext_ctxt, sp: span, s: str) -> @ast::expr {
-    let lit = ast::lit_str(s);
+    let lit = ast::lit_str(@s);
     ret mk_lit(cx, sp, lit);
 }
 fn mk_int(cx: ext_ctxt, sp: span, i: int) -> @ast::expr {
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 278321ec8bc..faf8e1a0868 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -3,13 +3,13 @@ import base::*;
 fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
                      _body: ast::mac_body) -> @ast::expr {
     let args = get_mac_args_no_max(cx,sp,arg,1u,"concat_idents");
-    let mut res: ast::ident = "";
+    let mut res = "";
     for args.each {|e|
-        res += expr_to_ident(cx, e, "expected an ident");
+        res += *expr_to_ident(cx, e, "expected an ident");
     }
 
     ret @{id: cx.next_id(),
-          node: ast::expr_path(@{span: sp, global: false, idents: [res],
+          node: ast::expr_path(@{span: sp, global: false, idents: [@res],
                                  rp: none, types: []}),
           span: sp};
 }
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 6a4d937f083..ebb56fa3b58 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -21,8 +21,8 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
     }
 }
 
-fn make_new_str(cx: ext_ctxt, sp: codemap::span, s: str) -> @ast::expr {
-    ret make_new_lit(cx, sp, ast::lit_str(s));
+fn make_new_str(cx: ext_ctxt, sp: codemap::span, +s: str) -> @ast::expr {
+    ret make_new_lit(cx, sp, ast::lit_str(@s));
 }
 //
 // Local Variables:
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 90487e27956..8bc1f7a3433 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -21,21 +21,21 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
               mac_invoc(pth, args, body) {
                 assert (vec::len(pth.idents) > 0u);
                 let extname = pth.idents[0];
-                alt exts.find(extname) {
+                alt exts.find(*extname) {
                   none {
                     cx.span_fatal(pth.span,
-                                  #fmt["macro undefined: '%s'", extname])
+                                  #fmt["macro undefined: '%s'", *extname])
                   }
                   some(item_decorator(_)) {
                     cx.span_fatal(
                         pth.span,
-                        #fmt["%s can only be used as a decorator", extname]);
+                        #fmt["%s can only be used as a decorator", *extname]);
                   }
                   some(normal({expander: exp, span: exp_sp})) {
                     let expanded = exp(cx, pth.span, args, body);
 
                     cx.bt_push(expanded_from({call_site: s,
-                                callie: {name: extname, span: exp_sp}}));
+                                callie: {name: *extname, span: exp_sp}}));
                     //keep going, outside-in
                     let fully_expanded = fld.fold_expr(expanded).node;
                     cx.bt_pop();
@@ -44,7 +44,7 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
                   }
                   some(macro_defining(ext)) {
                     let named_extension = ext(cx, pth.span, args, body);
-                    exts.insert(named_extension.ident, named_extension.ext);
+                    exts.insert(*named_extension.ident, named_extension.ext);
                     (ast::expr_rec([], none), s)
                   }
                 }
@@ -74,7 +74,7 @@ fn expand_mod_items(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
               ast::meta_name_value(n, _) { n }
               ast::meta_list(n, _) { n }
             };
-            alt exts.find(mname) {
+            alt exts.find(*mname) {
               none | some(normal(_)) | some(macro_defining(_)) {
                 items
               }
diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs
index aceeed4b9e8..4725f5a1977 100644
--- a/src/libsyntax/ext/fmt.rs
+++ b/src/libsyntax/ext/fmt.rs
@@ -36,9 +36,10 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
 fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: [piece], args: [@ast::expr])
    -> @ast::expr {
     fn make_path_vec(_cx: ext_ctxt, ident: ast::ident) -> [ast::ident] {
-        ret ["extfmt", "rt", ident];
+        ret [@"extfmt", @"rt", ident];
     }
-    fn make_rt_path_expr(cx: ext_ctxt, sp: span, ident: str) -> @ast::expr {
+    fn make_rt_path_expr(cx: ext_ctxt, sp: span,
+                         ident: ast::ident) -> @ast::expr {
         let path = make_path_vec(cx, ident);
         ret mk_path(cx, sp, path);
     }
@@ -57,18 +58,18 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: [piece], args: [@ast::expr])
                   flag_sign_always { fstr = "flag_sign_always"; }
                   flag_alternate { fstr = "flag_alternate"; }
                 }
-                flagexprs += [make_rt_path_expr(cx, sp, fstr)];
+                flagexprs += [make_rt_path_expr(cx, sp, @fstr)];
             }
             ret mk_vec_e(cx, sp, flagexprs);
         }
         fn make_count(cx: ext_ctxt, sp: span, cnt: count) -> @ast::expr {
             alt cnt {
               count_implied {
-                ret make_rt_path_expr(cx, sp, "count_implied");
+                ret make_rt_path_expr(cx, sp, @"count_implied");
               }
               count_is(c) {
                 let count_lit = mk_int(cx, sp, c);
-                let count_is_path = make_path_vec(cx, "count_is");
+                let count_is_path = make_path_vec(cx, @"count_is");
                 let count_is_args = [count_lit];
                 ret mk_call(cx, sp, count_is_path, count_is_args);
               }
@@ -88,16 +89,16 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: [piece], args: [@ast::expr])
               ty_octal { rt_type = "ty_octal"; }
               _ { rt_type = "ty_default"; }
             }
-            ret make_rt_path_expr(cx, sp, rt_type);
+            ret make_rt_path_expr(cx, sp, @rt_type);
         }
         fn make_conv_rec(cx: ext_ctxt, sp: span, flags_expr: @ast::expr,
                          width_expr: @ast::expr, precision_expr: @ast::expr,
                          ty_expr: @ast::expr) -> @ast::expr {
             ret mk_rec_e(cx, sp,
-                         [{ident: "flags", ex: flags_expr},
-                          {ident: "width", ex: width_expr},
-                          {ident: "precision", ex: precision_expr},
-                          {ident: "ty", ex: ty_expr}]);
+                         [{ident: @"flags", ex: flags_expr},
+                          {ident: @"width", ex: width_expr},
+                          {ident: @"precision", ex: precision_expr},
+                          {ident: @"ty", ex: ty_expr}]);
         }
         let rt_conv_flags = make_flags(cx, sp, cnv.flags);
         let rt_conv_width = make_count(cx, sp, cnv.width);
@@ -109,7 +110,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: [piece], args: [@ast::expr])
     fn make_conv_call(cx: ext_ctxt, sp: span, conv_type: str, cnv: conv,
                       arg: @ast::expr) -> @ast::expr {
         let fname = "conv_" + conv_type;
-        let path = make_path_vec(cx, fname);
+        let path = make_path_vec(cx, @fname);
         let cnv_expr = make_rt_conv_expr(cx, sp, cnv);
         let args = [cnv_expr, arg];
         ret mk_call(cx, arg.span, path, args);
diff --git a/src/libsyntax/ext/qquote.rs b/src/libsyntax/ext/qquote.rs
index 1a7ae69e79d..316ac7603fb 100644
--- a/src/libsyntax/ext/qquote.rs
+++ b/src/libsyntax/ext/qquote.rs
@@ -35,7 +35,7 @@ impl of qq_helper for @ast::crate {
     fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_crate(*self, cx, v);}
     fn extract_mac() -> option<ast::mac_> {fail}
     fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
-        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_crate"])
+        mk_path(cx, sp, [@"syntax", @"ext", @"qquote", @"parse_crate"])
     }
     fn get_fold_fn() -> str {"fold_crate"}
 }
@@ -49,7 +49,7 @@ impl of qq_helper for @ast::expr {
         }
     }
     fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
-        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_expr"])
+        mk_path(cx, sp, [@"syntax", @"ext", @"qquote", @"parse_expr"])
     }
     fn get_fold_fn() -> str {"fold_expr"}
 }
@@ -63,7 +63,7 @@ impl of qq_helper for @ast::ty {
         }
     }
     fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
-        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_ty"])
+        mk_path(cx, sp, [@"syntax", @"ext", @"qquote", @"parse_ty"])
     }
     fn get_fold_fn() -> str {"fold_ty"}
 }
@@ -72,7 +72,7 @@ impl of qq_helper for @ast::item {
     fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_item(self, cx, v);}
     fn extract_mac() -> option<ast::mac_> {fail}
     fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
-        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_item"])
+        mk_path(cx, sp, [@"syntax", @"ext", @"qquote", @"parse_item"])
     }
     fn get_fold_fn() -> str {"fold_item"}
 }
@@ -81,7 +81,7 @@ impl of qq_helper for @ast::stmt {
     fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_stmt(self, cx, v);}
     fn extract_mac() -> option<ast::mac_> {fail}
     fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
-        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_stmt"])
+        mk_path(cx, sp, [@"syntax", @"ext", @"qquote", @"parse_stmt"])
     }
     fn get_fold_fn() -> str {"fold_stmt"}
 }
@@ -90,7 +90,7 @@ impl of qq_helper for @ast::pat {
     fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_pat(self, cx, v);}
     fn extract_mac() -> option<ast::mac_> {fail}
     fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
-        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_pat"])
+        mk_path(cx, sp, [@"syntax", @"ext", @"qquote", @"parse_pat"])
     }
     fn get_fold_fn() -> str {"fold_pat"}
 }
@@ -146,7 +146,7 @@ fn expand_ast(ecx: ext_ctxt, _sp: span,
         }
         alt (args[0].node) {
           ast::expr_path(@{idents: id, _}) if vec::len(id) == 1u
-              {what = id[0]}
+              {what = *id[0]}
           _ {ecx.span_fatal(args[0].span, "expected an identifier");}
         }
     }
@@ -230,20 +230,21 @@ fn finish<T: qq_helper>
     let cx = ecx;
 
     let cfg_call = {||
-        mk_call_(cx, sp, mk_access(cx, sp, ["ext_cx"], "cfg"), [])
+        mk_call_(cx, sp, mk_access(cx, sp, [@"ext_cx"], @"cfg"), [])
     };
 
     let parse_sess_call = {||
-        mk_call_(cx, sp, mk_access(cx, sp, ["ext_cx"], "parse_sess"), [])
+        mk_call_(cx, sp, mk_access(cx, sp, [@"ext_cx"], @"parse_sess"), [])
     };
 
     let pcall = mk_call(cx,sp,
-                       ["syntax", "parse", "parser",
-                        "parse_from_source_str"],
+                       [@"syntax", @"parse", @"parser",
+                        @"parse_from_source_str"],
                        [node.mk_parse_fn(cx,sp),
                         mk_str(cx,sp, fname),
                         mk_call(cx,sp,
-                                ["syntax","ext","qquote", "mk_file_substr"],
+                                [@"syntax",@"ext",
+                                 @"qquote", @"mk_file_substr"],
                                 [mk_str(cx,sp, loc.file.name),
                                  mk_uint(cx,sp, loc.line),
                                  mk_uint(cx,sp, loc.col)]),
@@ -255,15 +256,16 @@ fn finish<T: qq_helper>
     let mut rcall = pcall;
     if (g_len > 0u) {
         rcall = mk_call(cx,sp,
-                        ["syntax", "ext", "qquote", "replace"],
+                        [@"syntax", @"ext", @"qquote", @"replace"],
                         [pcall,
                          mk_vec_e(cx,sp, qcx.gather.map_to_vec {|g|
                              mk_call(cx,sp,
-                                     ["syntax", "ext", "qquote", g.constr],
+                                     [@"syntax", @"ext",
+                                      @"qquote", @g.constr],
                                      [g.e])}),
                          mk_path(cx,sp,
-                                 ["syntax", "ext", "qquote",
-                                  node.get_fold_fn()])]);
+                                 [@"syntax", @"ext", @"qquote",
+                                  @node.get_fold_fn()])]);
     }
     ret rcall;
 }
diff --git a/src/libsyntax/ext/simplext.rs b/src/libsyntax/ext/simplext.rs
index 764c484c8e3..e2d16299b22 100644
--- a/src/libsyntax/ext/simplext.rs
+++ b/src/libsyntax/ext/simplext.rs
@@ -1,5 +1,5 @@
 import codemap::span;
-import std::map::{hashmap, str_hash};
+import std::map::{hashmap, str_hash, box_str_hash};
 import dvec::{dvec, extensions};
 
 import base::*;
@@ -146,7 +146,7 @@ fn acumm_bindings(_cx: ext_ctxt, _b_dest: bindings, _b_src: bindings) { }
 
 fn pattern_to_selectors(cx: ext_ctxt, e: @expr) -> binders {
     let res: binders =
-        {real_binders: str_hash::<selector>(),
+        {real_binders: box_str_hash::<selector>(),
          literal_ast_matchers: dvec()};
     //this oughta return binders instead, but macro args are a sequence of
     //expressions, rather than a single expression
@@ -162,7 +162,7 @@ bindings. Most of the work is done in p_t_s, which generates the
 selectors. */
 
 fn use_selectors_to_bind(b: binders, e: @expr) -> option<bindings> {
-    let res = str_hash::<arb_depth<matchable>>();
+    let res = box_str_hash::<arb_depth<matchable>>();
     //need to do this first, to check vec lengths.
     for b.literal_ast_matchers.each {|sel|
         alt sel(match_expr(e)) { none { ret none; } _ { } }
@@ -240,7 +240,7 @@ fn follow_for_trans(cx: ext_ctxt, mmaybe: option<arb_depth<matchable>>,
 
 /* helper for transcribe_exprs: what vars from `b` occur in `e`? */
 fn free_vars(b: bindings, e: @expr, it: fn(ident)) {
-    let idents: hashmap<ident, ()> = str_hash::<()>();
+    let idents: hashmap<ident, ()> = box_str_hash::<()>();
     fn mark_ident(&&i: ident, _fld: ast_fold, b: bindings,
                   idents: hashmap<ident, ()>) -> ident {
         if b.contains_key(i) { idents.insert(i, ()); }
@@ -282,8 +282,8 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mut [uint],
                         let len = vec::len(*ms);
                         if old_len != len {
                             let msg =
-                                #fmt["'%s' occurs %u times, but ", fv, len] +
-                                    #fmt["'%s' occurs %u times", old_name,
+                                #fmt["'%s' occurs %u times, but ", *fv, len] +
+                                    #fmt["'%s' occurs %u times", *old_name,
                                          old_len];
                             cx.span_fatal(repeat_me.span, msg);
                         }
@@ -672,7 +672,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
                      _body: ast::mac_body) -> base::macro_def {
     let args = get_mac_args_no_max(cx, sp, arg, 0u, "macro");
 
-    let mut macro_name: option<str> = none;
+    let mut macro_name: option<@str> = none;
     let mut clauses: [@clause] = [];
     for args.each {|arg|
         alt arg.node {
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 0680194ea6b..23c6a3714c3 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -36,19 +36,20 @@ fn expand_file(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
     get_mac_args(cx, sp, arg, 0u, option::some(0u), "file");
     let { file: @{ name: filename, _ }, _ } =
         codemap::lookup_char_pos(cx.codemap(), sp.lo);
-    ret make_new_lit(cx, sp, ast::lit_str(filename));
+    ret make_new_lit(cx, sp, ast::lit_str(@filename));
 }
 
 fn expand_stringify(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
                     _body: ast::mac_body) -> @ast::expr {
     let args = get_mac_args(cx, sp, arg, 1u, option::some(1u), "stringify");
-    ret make_new_lit(cx, sp, ast::lit_str(pprust::expr_to_str(args[0])));
+    ret make_new_lit(cx, sp, ast::lit_str(@pprust::expr_to_str(args[0])));
 }
 
 fn expand_mod(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body)
     -> @ast::expr {
     get_mac_args(cx, sp, arg, 0u, option::some(0u), "file");
-    ret make_new_lit(cx, sp, ast::lit_str(str::connect(cx.mod_path(), "::")));
+    ret make_new_lit(cx, sp, ast::lit_str(
+        @str::connect(cx.mod_path().map({|x|*x}), "::")));
 }
 
 fn expand_include(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
@@ -75,7 +76,7 @@ fn expand_include_str(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
       }
     }
 
-    ret make_new_lit(cx, sp, ast::lit_str(result::unwrap(res)));
+    ret make_new_lit(cx, sp, ast::lit_str(@result::unwrap(res)));
 }
 
 fn expand_include_bin(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs
index 0520993de74..c8e62a2245d 100644
--- a/src/libsyntax/parse/common.rs
+++ b/src/libsyntax/parse/common.rs
@@ -81,7 +81,7 @@ impl parser_common for parser {
     fn token_is_keyword(word: str, ++tok: token::token) -> bool {
         self.require_keyword(word);
         alt tok {
-          token::IDENT(sid, false) { str::eq(word, self.get_str(sid)) }
+          token::IDENT(sid, false) { str::eq(word, *self.get_str(sid)) }
           _ { false }
         }
     }
@@ -97,7 +97,7 @@ impl parser_common for parser {
         // workaround LLVM bug #13042
         alt @self.token {
           @token::IDENT(sid, false) {
-            if str::eq(word, self.get_str(sid)) {
+            if str::eq(word, *self.get_str(sid)) {
                 self.bump();
                 ret true;
             } else { ret false; }
@@ -128,7 +128,7 @@ impl parser_common for parser {
         }
     }
 
-    fn check_restricted_keywords_(w: ast::ident) {
+    fn check_restricted_keywords_(w: str) {
         if self.is_restricted_keyword(w) {
             self.fatal("found `" + w + "` in restricted position");
         }
diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs
index 254d5cc5d5d..4b5632124d8 100644
--- a/src/libsyntax/parse/eval.rs
+++ b/src/libsyntax/parse/eval.rs
@@ -75,7 +75,7 @@ fn parse_companion_mod(cx: ctx, prefix: str, suffix: option<str>)
     }
 }
 
-fn cdir_path_opt(id: str, attrs: [ast::attribute]) -> str {
+fn cdir_path_opt(id: ast::ident, attrs: [ast::attribute]) -> @str {
     alt ::attr::first_attr_value_str_by_name(attrs, "path") {
       some(d) {
         ret d;
@@ -89,11 +89,11 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str,
                         &items: [@ast::item]) {
     alt cdir.node {
       ast::cdir_src_mod(id, attrs) {
-        let file_path = cdir_path_opt(id + ".rs", attrs);
+        let file_path = cdir_path_opt(@(*id + ".rs"), attrs);
         let full_path =
-            if path::path_is_absolute(file_path) {
-                file_path
-            } else { prefix + path::path_sep() + file_path };
+            if path::path_is_absolute(*file_path) {
+                *file_path
+            } else { prefix + path::path_sep() + *file_path };
         let p0 =
             new_parser_from_file(cx.sess, cx.cfg, full_path, SOURCE_FILE);
         let inner_attrs = p0.parse_inner_attrs_and_next();
@@ -112,9 +112,9 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str,
       ast::cdir_dir_mod(id, cdirs, attrs) {
         let path = cdir_path_opt(id, attrs);
         let full_path =
-            if path::path_is_absolute(path) {
-                path
-            } else { prefix + path::path_sep() + path };
+            if path::path_is_absolute(*path) {
+                *path
+            } else { prefix + path::path_sep() + *path };
         let (m0, a0) = eval_crate_directives_to_mod(
             cx, cdirs, full_path, none);
         let i =
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 828cd5ce7d4..975e9031877 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -151,8 +151,8 @@ class parser {
     fn warn(m: str) {
         self.sess.span_diagnostic.span_warn(copy self.span, m)
     }
-    fn get_str(i: token::str_num) -> str {
-        *interner::get(*self.reader.interner, i)
+    fn get_str(i: token::str_num) -> @str {
+        interner::get(*self.reader.interner, i)
     }
     fn get_id() -> node_id { next_node_id(self.sess) }
 
@@ -178,7 +178,7 @@ class parser {
                 let name = self.parse_value_ident();
                 p.bump();
                 name
-            } else { "" };
+            } else { @"" };
 
             {mode: mode, ty: p.parse_ty(false), ident: name,
              id: p.get_id()}
@@ -229,7 +229,7 @@ class parser {
     fn ident_index(args: [arg], i: ident) -> uint {
         let mut j = 0u;
         for args.each {|a| if a.ident == i { ret j; } j += 1u; }
-        self.fatal("unbound variable `" + i + "` in constraint arg");
+        self.fatal("unbound variable `" + *i + "` in constraint arg");
     }
 
     fn parse_type_constr_arg() -> @ty_constr_arg {
@@ -315,7 +315,7 @@ class parser {
         }
     }
 
-    fn region_from_name(s: option<str>) -> @region {
+    fn region_from_name(s: option<@str>) -> @region {
         let r = alt s {
           some (string) { re_named(string) }
           none { re_anon }
@@ -1858,13 +1858,13 @@ class parser {
 
     fn parse_method_name() -> ident {
         alt copy self.token {
-          token::BINOP(op) { self.bump(); token::binop_to_str(op) }
-          token::NOT { self.bump(); "!" }
-          token::LBRACKET { self.bump(); self.expect(token::RBRACKET); "[]" }
+          token::BINOP(op) { self.bump(); @token::binop_to_str(op) }
+          token::NOT { self.bump(); @"!" }
+          token::LBRACKET { self.bump(); self.expect(token::RBRACKET); @"[]" }
           _ {
             let id = self.parse_value_ident();
-            if id == "unary" && self.eat(token::BINOP(token::MINUS)) {
-                "unary-"
+            if id == @"unary" && self.eat(token::BINOP(token::MINUS)) {
+                @"unary-"
             }
             else { id }
           }
@@ -1969,7 +1969,7 @@ class parser {
         // Hack.  But then, this whole function is in service of a hack.
         let a_r = alt rp {
           rp_none { none }
-          rp_self { some(self.region_from_name(some("self"))) }
+          rp_self { some(self.region_from_name(some(@"self"))) }
         };
 
         @{span: s, global: false, idents: [i],
@@ -2243,7 +2243,7 @@ class parser {
         let mut variants: [variant] = [];
         // Newtype syntax
         if self.token == token::EQ {
-            self.check_restricted_keywords_(id);
+            self.check_restricted_keywords_(*id);
             self.bump();
             let ty = self.parse_ty(false);
             self.expect(token::SEMI);
@@ -2381,7 +2381,7 @@ class parser {
         let lo = self.span.lo;
         let first_ident = self.parse_ident();
         let mut path = [first_ident];
-        #debug("parsed view_path: %s", first_ident);
+        #debug("parsed view_path: %s", *first_ident);
         alt self.token {
           token::EQ {
             // x = foo::bar
@@ -2504,7 +2504,7 @@ class parser {
                       config: self.cfg});
     }
 
-    fn parse_str() -> str {
+    fn parse_str() -> @str {
         alt copy self.token {
           token::LIT_STR(s) { self.bump(); self.get_str(s) }
           _ {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 97135a7bb75..a63e3139b5b 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -342,7 +342,7 @@ fn print_region(s: ps, region: @ast::region) {
       ast::re_anon { word_space(s, "&"); }
       ast::re_named(name) {
         word(s.s, "&");
-        word_space(s, name);
+        word_space(s, *name);
       }
     }
 }
@@ -382,7 +382,7 @@ fn print_type_ex(s: ps, &&ty: @ast::ty, print_colons: bool) {
         fn print_field(s: ps, f: ast::ty_field) {
             cbox(s, indent_unit);
             print_mutability(s, f.node.mt.mutbl);
-            word(s.s, f.node.ident);
+            word(s.s, *f.node.ident);
             word_space(s, ":");
             print_type(s, f.node.mt.ty);
             end(s);
@@ -443,7 +443,7 @@ fn print_item(s: ps, &&item: @ast::item) {
     alt item.node {
       ast::item_const(ty, expr) {
         head(s, "const");
-        word_space(s, item.ident + ":");
+        word_space(s, *item.ident + ":");
         print_type(s, ty);
         space(s.s);
         end(s); // end the head-ibox
@@ -461,7 +461,7 @@ fn print_item(s: ps, &&item: @ast::item) {
       }
       ast::item_mod(_mod) {
         head(s, "mod");
-        word_nbsp(s, item.ident);
+        word_nbsp(s, *item.ident);
         bopen(s);
         print_mod(s, _mod, item.attrs);
         bclose(s, item.span);
@@ -469,7 +469,7 @@ fn print_item(s: ps, &&item: @ast::item) {
       ast::item_native_mod(nmod) {
         head(s, "native");
         word_nbsp(s, "mod");
-        word_nbsp(s, item.ident);
+        word_nbsp(s, *item.ident);
         bopen(s);
         print_native_mod(s, nmod, item.attrs);
         bclose(s, item.span);
@@ -478,7 +478,7 @@ fn print_item(s: ps, &&item: @ast::item) {
         ibox(s, indent_unit);
         ibox(s, 0u);
         word_nbsp(s, "type");
-        word(s.s, item.ident);
+        word(s.s, *item.ident);
         print_region_param(s, rp);
         print_type_params(s, params);
         end(s); // end the inner ibox
@@ -492,13 +492,13 @@ fn print_item(s: ps, &&item: @ast::item) {
       ast::item_enum(variants, params, rp) {
         let newtype =
             vec::len(variants) == 1u &&
-                str::eq(item.ident, variants[0].node.name) &&
+                str::eq(*item.ident, *variants[0].node.name) &&
                 vec::len(variants[0].node.args) == 1u;
         if newtype {
             ibox(s, indent_unit);
             word_space(s, "enum");
         } else { head(s, "enum"); }
-        word(s.s, item.ident);
+        word(s.s, *item.ident);
         print_region_param(s, rp);
         print_type_params(s, params);
         space(s.s);
@@ -524,7 +524,7 @@ fn print_item(s: ps, &&item: @ast::item) {
       }
       ast::item_class(tps, ifaces, items, ctor, m_dtor, rp) {
           head(s, "class");
-          word_nbsp(s, item.ident);
+          word_nbsp(s, *item.ident);
           print_region_param(s, rp);
           print_type_params(s, tps);
           word_space(s, "implements");
@@ -570,7 +570,7 @@ fn print_item(s: ps, &&item: @ast::item) {
                       ast::class_mutable { word_nbsp(s, "mut"); }
                       _ {}
                     }
-                    word(s.s, nm);
+                    word(s.s, *nm);
                     word_nbsp(s, ":");
                     print_type(s, t);
                     word(s.s, ";");
@@ -588,7 +588,7 @@ fn print_item(s: ps, &&item: @ast::item) {
        }
       ast::item_impl(tps, rp, ifce, ty, methods) {
         head(s, "impl");
-        word(s.s, item.ident);
+        word(s.s, *item.ident);
         print_region_param(s, rp);
         print_type_params(s, tps);
         space(s.s);
@@ -608,7 +608,7 @@ fn print_item(s: ps, &&item: @ast::item) {
       }
       ast::item_iface(tps, rp, methods) {
         head(s, "iface");
-        word(s.s, item.ident);
+        word(s.s, *item.ident);
         print_region_param(s, rp);
         print_type_params(s, tps);
         word(s.s, " ");
@@ -627,18 +627,18 @@ fn print_item(s: ps, &&item: @ast::item) {
 fn print_res(s: ps, decl: ast::fn_decl, name: ast::ident,
              typarams: [ast::ty_param], rp: ast::region_param) {
     head(s, "resource");
-    word(s.s, name);
+    word(s.s, *name);
     print_region_param(s, rp);
     print_type_params(s, typarams);
     popen(s);
-    word_space(s, decl.inputs[0].ident + ":");
+    word_space(s, *decl.inputs[0].ident + ":");
     print_type(s, decl.inputs[0].ty);
     pclose(s);
     space(s.s);
 }
 
 fn print_variant(s: ps, v: ast::variant) {
-    word(s.s, v.node.name);
+    word(s.s, *v.node.name);
     if vec::len(v.node.args) > 0u {
         popen(s);
         fn print_variant_arg(s: ps, arg: ast::variant_arg) {
@@ -892,7 +892,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
         fn print_field(s: ps, field: ast::field) {
             ibox(s, indent_unit);
             if field.node.mutbl == ast::m_mutbl { word_nbsp(s, "mut"); }
-            word(s.s, field.node.ident);
+            word(s.s, *field.node.ident);
             word_space(s, ":");
             print_expr(s, field.node.expr);
             end(s);
@@ -1089,7 +1089,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
             print_expr_parens_if_not_bot(s, expr);
         }
         word(s.s, ".");
-        word(s.s, id);
+        word(s.s, *id);
         if vec::len(tys) > 0u {
             word(s.s, "::<");
             commasep(s, inconsistent, tys, print_type);
@@ -1222,7 +1222,7 @@ fn print_decl(s: ps, decl: @ast::decl) {
     }
 }
 
-fn print_ident(s: ps, ident: ast::ident) { word(s.s, ident); }
+fn print_ident(s: ps, ident: ast::ident) { word(s.s, *ident); }
 
 fn print_for_decl(s: ps, loc: @ast::local, coll: @ast::expr) {
     print_local_decl(s, loc);
@@ -1237,7 +1237,7 @@ fn print_path(s: ps, &&path: @ast::path, colons_before_params: bool) {
     let mut first = true;
     for path.idents.each {|id|
         if first { first = false; } else { word(s.s, "::"); }
-        word(s.s, id);
+        word(s.s, *id);
     }
     if path.rp.is_some() || !path.types.is_empty() {
         if colons_before_params { word(s.s, "::"); }
@@ -1290,7 +1290,7 @@ fn print_pat(s: ps, &&pat: @ast::pat) {
         word(s.s, "{");
         fn print_field(s: ps, f: ast::field_pat) {
             cbox(s, indent_unit);
-            word(s.s, f.ident);
+            word(s.s, *f.ident);
             word_space(s, ":");
             print_pat(s, f.pat);
             end(s);
@@ -1327,7 +1327,7 @@ fn print_fn(s: ps, decl: ast::fn_decl, name: ast::ident,
       ast::impure_fn { head(s, "fn") }
       _ { head(s, purity_to_str(decl.purity) + " fn") }
     }
-    word(s.s, name);
+    word(s.s, *name);
     print_type_params(s, typarams);
     print_fn_args_and_ret(s, decl, []);
 }
@@ -1341,7 +1341,7 @@ fn print_fn_args(s: ps, decl: ast::fn_decl,
             if first { first = false; } else { word_space(s, ","); }
             if cap_item.is_move { word_nbsp(s, "move") }
             else { word_nbsp(s, "copy") }
-            word(s.s, cap_item.name);
+            word(s.s, *cap_item.name);
         }
     }
 }
@@ -1418,7 +1418,7 @@ fn print_type_params(s: ps, &&params: [ast::ty_param]) {
     if vec::len(params) > 0u {
         word(s.s, "<");
         fn printParam(s: ps, param: ast::ty_param) {
-            word(s.s, param.ident);
+            word(s.s, *param.ident);
             print_bounds(s, param.bounds);
         }
         commasep(s, inconsistent, params, printParam);
@@ -1429,14 +1429,14 @@ fn print_type_params(s: ps, &&params: [ast::ty_param]) {
 fn print_meta_item(s: ps, &&item: @ast::meta_item) {
     ibox(s, indent_unit);
     alt item.node {
-      ast::meta_word(name) { word(s.s, name); }
+      ast::meta_word(name) { word(s.s, *name); }
       ast::meta_name_value(name, value) {
-        word_space(s, name);
+        word_space(s, *name);
         word_space(s, "=");
         print_literal(s, @value);
       }
       ast::meta_list(name, items) {
-        word(s.s, name);
+        word(s.s, *name);
         popen(s);
         commasep(s, consistent, items, print_meta_item);
         pclose(s);
@@ -1449,7 +1449,7 @@ fn print_view_path(s: ps, &&vp: @ast::view_path) {
     alt vp.node {
       ast::view_path_simple(ident, path, _) {
         if path.idents[vec::len(path.idents)-1u] != ident {
-            word_space(s, ident);
+            word_space(s, *ident);
             word_space(s, "=");
         }
         print_path(s, path, false);
@@ -1464,7 +1464,7 @@ fn print_view_path(s: ps, &&vp: @ast::view_path) {
         print_path(s, path, false);
         word(s.s, "::{");
         commasep(s, inconsistent, idents) {|s, w|
-            word(s.s, w.node.name)
+            word(s.s, *w.node.name)
         }
         word(s.s, "}");
       }
@@ -1481,7 +1481,7 @@ fn print_view_item(s: ps, item: @ast::view_item) {
     alt item.node {
       ast::view_item_use(id, mta, _) {
         head(s, "use");
-        word(s.s, id);
+        word(s.s, *id);
         if vec::len(mta) > 0u {
             popen(s);
             commasep(s, consistent, mta, print_meta_item);
@@ -1529,11 +1529,11 @@ fn print_arg(s: ps, input: ast::arg) {
     print_arg_mode(s, input.mode);
     alt input.ty.node {
       ast::ty_infer {
-        word(s.s, input.ident);
+        word(s.s, *input.ident);
       }
       _ {
-        if str::len(input.ident) > 0u {
-            word_space(s, input.ident + ":");
+        if str::len(*input.ident) > 0u {
+            word_space(s, *input.ident + ":");
         }
         print_type(s, input.ty);
       }
@@ -1546,7 +1546,7 @@ fn print_ty_fn(s: ps, opt_proto: option<ast::proto>,
                tps: option<[ast::ty_param]>) {
     ibox(s, indent_unit);
     word(s.s, opt_proto_to_str(opt_proto));
-    alt id { some(id) { word(s.s, " "); word(s.s, id); } _ { } }
+    alt id { some(id) { word(s.s, " "); word(s.s, *id); } _ { } }
     alt tps { some(tps) { print_type_params(s, tps); } _ { } }
     zerobreak(s.s);
     popen(s);
@@ -1608,7 +1608,7 @@ fn print_literal(s: ps, &&lit: @ast::lit) {
       _ {}
     }
     alt lit.node {
-      ast::lit_str(st) { print_string(s, st); }
+      ast::lit_str(st) { print_string(s, *st); }
       ast::lit_int(ch, ast::ty_char) {
         word(s.s, "'" + char::escape_default(ch as char) + "'");
       }
@@ -1640,7 +1640,7 @@ fn print_literal(s: ps, &&lit: @ast::lit) {
         }
       }
       ast::lit_float(f, t) {
-        word(s.s, f + ast_util::float_ty_to_str(t));
+        word(s.s, *f + ast_util::float_ty_to_str(t));
       }
       ast::lit_nil { word(s.s, "()"); }
       ast::lit_bool(val) {
@@ -1804,7 +1804,7 @@ fn constrs_str<T>(constrs: [T], elt: fn(T) -> str) -> str {
 }
 
 fn fn_arg_idx_to_str(decl: ast::fn_decl, &&idx: uint) -> str {
-    decl.inputs[idx].ident
+    *decl.inputs[idx].ident
 }
 
 fn opt_proto_to_str(opt_p: option<ast::proto>) -> str {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index fa0286ded81..8b70848b248 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -29,8 +29,8 @@ fn name_of_fn(fk: fn_kind) -> ident {
     alt fk {
       fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _, _)
           | fk_ctor(name, _, _, _) { /* FIXME: bad */ copy name }
-      fk_anon(*) | fk_fn_block(*) { "anon" }
-      fk_dtor(*)                  { "drop" }
+      fk_anon(*) | fk_fn_block(*) { @"anon" }
+      fk_dtor(*)                  { @"drop" }
     }
 }