about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-05-10 01:55:54 -0700
committerbors <bors@rust-lang.org>2013-05-10 01:55:54 -0700
commite9d0018abf8dd0c692db4cfe8f5d1bd1c150d643 (patch)
treef52065d76f022ca0afe150daaa63c9ddc9157060 /src/libsyntax
parentf04eb37c7ea19bbd2cff12d15816873e0a46fc86 (diff)
parent1393c3a3f438c896083405dca501c8cf05767c65 (diff)
downloadrust-e9d0018abf8dd0c692db4cfe8f5d1bd1c150d643.tar.gz
rust-e9d0018abf8dd0c692db4cfe8f5d1bd1c150d643.zip
auto merge of #6356 : dotdash/rust/strinterner, r=pcwalton
&str can be turned into @~str on demand, using to_owned(), so for
strings, we can create a specialized interner that accepts &str for
intern() and find() but stores and returns @~str.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ext/auto_encode.rs144
-rw-r--r--src/libsyntax/ext/base.rs6
-rw-r--r--src/libsyntax/ext/build.rs8
-rw-r--r--src/libsyntax/ext/concat_idents.rs2
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs6
-rw-r--r--src/libsyntax/ext/deriving/cmp/totalord.rs16
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs70
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs60
-rw-r--r--src/libsyntax/ext/deriving/mod.rs6
-rw-r--r--src/libsyntax/ext/deriving/rand.rs12
-rw-r--r--src/libsyntax/ext/deriving/to_str.rs8
-rw-r--r--src/libsyntax/ext/deriving/ty.rs2
-rw-r--r--src/libsyntax/ext/fmt.rs61
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs14
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs38
-rw-r--r--src/libsyntax/ext/quote.rs36
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs4
-rw-r--r--src/libsyntax/parse/lexer.rs44
-rw-r--r--src/libsyntax/parse/mod.rs12
-rw-r--r--src/libsyntax/parse/token.rs82
-rw-r--r--src/libsyntax/print/pprust.rs4
-rw-r--r--src/libsyntax/util/interner.rs56
23 files changed, 374 insertions, 319 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index c8fc04eaea1..5908d0c56f4 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -93,7 +93,7 @@ impl<D:Decoder> Decodable<D> for ident {
             Some(intr) => intr
         };
 
-        (*intr).intern(@d.read_str())
+        (*intr).intern(d.read_str())
     }
 }
 
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 5bd4f89a3b3..1d3af61be70 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -244,7 +244,7 @@ trait ExtCtxtMethods {
     fn expr_blk(&self, expr: @ast::expr) -> ast::blk;
     fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
     fn expr_path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
-    fn expr_var(&self, span: span, var: ~str) -> @ast::expr;
+    fn expr_var(&self, span: span, var: &str) -> @ast::expr;
     fn expr_field(&self, span: span, expr: @ast::expr, ident: ast::ident)
                   -> @ast::expr;
     fn expr_call(&self, span: span, expr: @ast::expr, args: ~[@ast::expr])
@@ -446,7 +446,7 @@ impl ExtCtxtMethods for @ext_ctxt {
         self.expr(span, ast::expr_path(self.path_global(span, strs)))
     }
 
-    fn expr_var(&self, span: span, var: ~str) -> @ast::expr {
+    fn expr_var(&self, span: span, var: &str) -> @ast::expr {
         self.expr_path(span, ~[self.ident_of(var)])
     }
 
@@ -583,13 +583,13 @@ fn mk_ser_impl(
     // Make a path to the std::serialize::Encodable typaram.
     let ty_param = cx.bind_path(
         span,
-        cx.ident_of(~"__S"),
+        cx.ident_of("__S"),
         cx.path_global(
             span,
             ~[
-                cx.ident_of(~"std"),
-                cx.ident_of(~"serialize"),
-                cx.ident_of(~"Encoder"),
+                cx.ident_of("std"),
+                cx.ident_of("serialize"),
+                cx.ident_of("Encoder"),
             ]
         ),
         @opt_vec::Empty
@@ -599,11 +599,11 @@ fn mk_ser_impl(
     let path = cx.path_tps_global(
         span,
         ~[
-            cx.ident_of(~"std"),
-            cx.ident_of(~"serialize"),
-            cx.ident_of(~"Encodable"),
+            cx.ident_of("std"),
+            cx.ident_of("serialize"),
+            cx.ident_of("Encodable"),
         ],
-        ~[cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[])]
+        ~[cx.ty_path(span, ~[cx.ident_of("__S")], ~[])]
     );
 
     mk_impl(
@@ -627,13 +627,13 @@ fn mk_deser_impl(
     // Make a path to the std::serialize::Decodable typaram.
     let ty_param = cx.bind_path(
         span,
-        cx.ident_of(~"__D"),
+        cx.ident_of("__D"),
         cx.path_global(
             span,
             ~[
-                cx.ident_of(~"std"),
-                cx.ident_of(~"serialize"),
-                cx.ident_of(~"Decoder"),
+                cx.ident_of("std"),
+                cx.ident_of("serialize"),
+                cx.ident_of("Decoder"),
             ]
         ),
         @opt_vec::Empty
@@ -643,11 +643,11 @@ fn mk_deser_impl(
     let path = cx.path_tps_global(
         span,
         ~[
-            cx.ident_of(~"std"),
-            cx.ident_of(~"serialize"),
-            cx.ident_of(~"Decodable"),
+            cx.ident_of("std"),
+            cx.ident_of("serialize"),
+            cx.ident_of("Decodable"),
         ],
-        ~[cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[])]
+        ~[cx.ty_path(span, ~[cx.ident_of("__D")], ~[])]
     );
 
     mk_impl(
@@ -671,7 +671,7 @@ fn mk_ser_method(
         node: ast::ty_rptr(
             None,
             ast::mt {
-                ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]),
+                ty: cx.ty_path(span, ~[cx.ident_of("__S")], ~[]),
                 mutbl: ast::m_mutbl
             }
         ),
@@ -685,7 +685,7 @@ fn mk_ser_method(
             id: cx.next_id(),
             node: ast::pat_ident(
                 ast::bind_by_copy,
-                ast_util::ident_to_path(span, cx.ident_of(~"__s")),
+                ast_util::ident_to_path(span, cx.ident_of("__s")),
                 None),
             span: span,
         },
@@ -705,7 +705,7 @@ fn mk_ser_method(
     };
 
     @ast::method {
-        ident: cx.ident_of(~"encode"),
+        ident: cx.ident_of("encode"),
         attrs: ~[],
         generics: ast_util::empty_generics(),
         self_ty: codemap::spanned {
@@ -733,7 +733,7 @@ fn mk_deser_method(
         node: ast::ty_rptr(
             None,
             ast::mt {
-                ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]),
+                ty: cx.ty_path(span, ~[cx.ident_of("__D")], ~[]),
                 mutbl: ast::m_mutbl
             }
         ),
@@ -749,7 +749,7 @@ fn mk_deser_method(
                 node: ast::pat_ident(ast::bind_by_copy,
                                      ast_util::ident_to_path(span,
                                                              cx.ident_of(
-                                                                ~"__d")),
+                                                                "__d")),
                                      None),
                 span: span,
             },
@@ -764,7 +764,7 @@ fn mk_deser_method(
     };
 
     @ast::method {
-        ident: cx.ident_of(~"decode"),
+        ident: cx.ident_of("decode"),
         attrs: ~[],
         generics: ast_util::empty_generics(),
         self_ty: codemap::spanned { node: ast::sty_static, span: span },
@@ -792,21 +792,21 @@ fn mk_struct_ser_impl(
                 span,
                 cx.expr_field(
                     span,
-                    cx.expr_var(span, ~"self"),
+                    cx.expr_var(span, "self"),
                     field.ident
                 ),
-                cx.ident_of(~"encode"),
-                ~[cx.expr_var(span, ~"__s")]
+                cx.ident_of("encode"),
+                ~[cx.expr_var(span, "__s")]
             ),
-            cx.ident_of(~"__s")
+            cx.ident_of("__s")
         );
 
         // ast for `__s.emit_struct_field($(name), $(idx), $(expr_lambda))`
         cx.stmt(
             cx.expr_method_call(
                 span,
-                cx.expr_var(span, ~"__s"),
-                cx.ident_of(~"emit_struct_field"),
+                cx.expr_var(span, "__s"),
+                cx.ident_of("emit_struct_field"),
                 ~[
                     cx.lit_str(span, @cx.str_of(field.ident)),
                     cx.lit_uint(span, idx),
@@ -819,12 +819,12 @@ fn mk_struct_ser_impl(
     // ast for `__s.emit_struct($(name), |__s| $(fields))`
     let ser_body = cx.expr_method_call(
         span,
-        cx.expr_var(span, ~"__s"),
-        cx.ident_of(~"emit_struct"),
+        cx.expr_var(span, "__s"),
+        cx.ident_of("emit_struct"),
         ~[
             cx.lit_str(span, @cx.str_of(ident)),
             cx.lit_uint(span, vec::len(fields)),
-            cx.lambda_stmts_1(span, fields, cx.ident_of(~"__s")),
+            cx.lambda_stmts_1(span, fields, cx.ident_of("__s")),
         ]
     );
 
@@ -845,22 +845,22 @@ fn mk_struct_deser_impl(
                 cx.expr_call(
                     span,
                     cx.expr_path_global(span, ~[
-                        cx.ident_of(~"std"),
-                        cx.ident_of(~"serialize"),
-                        cx.ident_of(~"Decodable"),
-                        cx.ident_of(~"decode"),
+                        cx.ident_of("std"),
+                        cx.ident_of("serialize"),
+                        cx.ident_of("Decodable"),
+                        cx.ident_of("decode"),
                     ]),
-                    ~[cx.expr_var(span, ~"__d")]
+                    ~[cx.expr_var(span, "__d")]
                 )
             ),
-            cx.ident_of(~"__d")
+            cx.ident_of("__d")
         );
 
         // ast for `__d.read_struct_field($(name), $(idx), $(expr_lambda))`
         let expr: @ast::expr = cx.expr_method_call(
             span,
-            cx.expr_var(span, ~"__d"),
-            cx.ident_of(~"read_struct_field"),
+            cx.expr_var(span, "__d"),
+            cx.ident_of("read_struct_field"),
             ~[
                 cx.lit_str(span, @cx.str_of(field.ident)),
                 cx.lit_uint(span, idx),
@@ -881,8 +881,8 @@ fn mk_struct_deser_impl(
     // ast for `read_struct($(name), |__d| $(fields))`
     let body = cx.expr_method_call(
         span,
-        cx.expr_var(span, ~"__d"),
-        cx.ident_of(~"read_struct"),
+        cx.expr_var(span, "__d"),
+        cx.ident_of("read_struct"),
         ~[
             cx.lit_str(span, @cx.str_of(ident)),
             cx.lit_uint(span, vec::len(fields)),
@@ -895,7 +895,7 @@ fn mk_struct_deser_impl(
                         None
                     )
                 ),
-                cx.ident_of(~"__d")
+                cx.ident_of("__d")
             ),
         ]
     );
@@ -997,8 +997,8 @@ fn ser_variant(
         // ast for `__s.emit_enum_variant_arg`
         let expr_emit = cx.expr_field(
             span,
-            cx.expr_var(span, ~"__s"),
-            cx.ident_of(~"emit_enum_variant_arg")
+            cx.expr_var(span, "__s"),
+            cx.ident_of("emit_enum_variant_arg")
         );
 
         // ast for `|__s| $(v).encode(__s)`
@@ -1006,10 +1006,10 @@ fn ser_variant(
             cx.expr_method_call(
                 span,
                  cx.expr_path(span, ~[names[a_idx]]),
-                 cx.ident_of(~"encode"),
-                ~[cx.expr_var(span, ~"__s")]
+                 cx.ident_of("encode"),
+                ~[cx.expr_var(span, "__s")]
             ),
-            cx.ident_of(~"__s")
+            cx.ident_of("__s")
         );
 
         // ast for `$(expr_emit)($(a_idx), $(expr_encode))`
@@ -1025,13 +1025,13 @@ fn ser_variant(
     // ast for `__s.emit_enum_variant($(name), $(idx), $(sz), $(lambda))`
     let body = cx.expr_method_call(
         span,
-        cx.expr_var(span, ~"__s"),
-        cx.ident_of(~"emit_enum_variant"),
+        cx.expr_var(span, "__s"),
+        cx.ident_of("emit_enum_variant"),
         ~[
             cx.lit_str(span, @cx.str_of(v_name)),
             cx.lit_uint(span, v_idx),
             cx.lit_uint(span, stmts.len()),
-            cx.lambda_stmts_1(span, stmts, cx.ident_of(~"__s")),
+            cx.lambda_stmts_1(span, stmts, cx.ident_of("__s")),
         ]
     );
 
@@ -1065,7 +1065,7 @@ fn mk_enum_ser_body(
         ast::expr_match(
             cx.expr(
                 span,
-                ast::expr_unary(ast::deref, cx.expr_var(span, ~"self"))
+                ast::expr_unary(ast::deref, cx.expr_var(span, "self"))
             ),
             arms
         )
@@ -1074,11 +1074,11 @@ fn mk_enum_ser_body(
     // ast for `__s.emit_enum($(name), || $(match_expr))`
     cx.expr_method_call(
         span,
-        cx.expr_var(span, ~"__s"),
-        cx.ident_of(~"emit_enum"),
+        cx.expr_var(span, "__s"),
+        cx.ident_of("emit_enum"),
         ~[
             cx.lit_str(span, @cx.str_of(name)),
-            cx.lambda_expr_1(match_expr, cx.ident_of(~"__s")),
+            cx.lambda_expr_1(match_expr, cx.ident_of("__s")),
         ]
     )
 }
@@ -1095,21 +1095,21 @@ fn mk_enum_deser_variant_nary(
             cx.expr_call(
                 span,
                 cx.expr_path_global(span, ~[
-                    cx.ident_of(~"std"),
-                    cx.ident_of(~"serialize"),
-                    cx.ident_of(~"Decodable"),
-                    cx.ident_of(~"decode"),
+                    cx.ident_of("std"),
+                    cx.ident_of("serialize"),
+                    cx.ident_of("Decodable"),
+                    cx.ident_of("decode"),
                 ]),
-                ~[cx.expr_var(span, ~"__d")]
+                ~[cx.expr_var(span, "__d")]
             ),
-            cx.ident_of(~"__d")
+            cx.ident_of("__d")
         );
 
         // ast for `__d.read_enum_variant_arg($(a_idx), $(expr_lambda))`
         cx.expr_method_call(
             span,
-            cx.expr_var(span, ~"__d"),
-            cx.ident_of(~"read_enum_variant_arg"),
+            cx.expr_var(span, "__d"),
+            cx.ident_of("read_enum_variant_arg"),
             ~[cx.lit_uint(span, idx), expr_lambda]
         )
     };
@@ -1205,7 +1205,7 @@ fn mk_enum_deser_body(
                             node: ast::pat_ident(
                                 ast::bind_by_copy,
                                 ast_util::ident_to_path(span,
-                                    ext_cx.ident_of(~"__d")),
+                                    ext_cx.ident_of("__d")),
                                 None),
                             span: span,
                         },
@@ -1223,7 +1223,7 @@ fn mk_enum_deser_body(
                             node: ast::pat_ident(
                                 ast::bind_by_copy,
                                 ast_util::ident_to_path(span,
-                                    ext_cx.ident_of(~"i")),
+                                    ext_cx.ident_of("i")),
                                 None),
                             span: span,
                         },
@@ -1240,7 +1240,7 @@ fn mk_enum_deser_body(
             ext_cx.expr_blk(
                 ext_cx.expr(
                     span,
-                    ast::expr_match(ext_cx.expr_var(span, ~"i"), arms)
+                    ast::expr_match(ext_cx.expr_var(span, "i"), arms)
                 )
             )
         )
@@ -1250,18 +1250,18 @@ fn mk_enum_deser_body(
     let expr_lambda = ext_cx.lambda_expr_1(
         ext_cx.expr_method_call(
             span,
-            ext_cx.expr_var(span, ~"__d"),
-            ext_cx.ident_of(~"read_enum_variant"),
+            ext_cx.expr_var(span, "__d"),
+            ext_cx.ident_of("read_enum_variant"),
             ~[expr_arm_names, expr_lambda]
         ),
-        ext_cx.ident_of(~"__d")
+        ext_cx.ident_of("__d")
     );
 
     // ast for `__d.read_enum($(e_name), $(expr_lambda))`
     ext_cx.expr_method_call(
         span,
-        ext_cx.expr_var(span, ~"__d"),
-        ext_cx.ident_of(~"read_enum"),
+        ext_cx.expr_var(span, "__d"),
+        ext_cx.ident_of("read_enum"),
         ~[
             ext_cx.lit_str(span, @ext_cx.str_of(name)),
             expr_lambda
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index da8f87d3891..ac825e9436a 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -232,7 +232,7 @@ pub trait ext_ctxt {
     fn set_trace_macros(&self, x: bool);
     /* for unhygienic identifier transformation */
     fn str_of(&self, id: ast::ident) -> ~str;
-    fn ident_of(&self, st: ~str) -> ast::ident;
+    fn ident_of(&self, st: &str) -> ast::ident;
 }
 
 pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg)
@@ -322,8 +322,8 @@ pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg)
         fn str_of(&self, id: ast::ident) -> ~str {
             copy *self.parse_sess.interner.get(id)
         }
-        fn ident_of(&self, st: ~str) -> ast::ident {
-            self.parse_sess.interner.intern(@/*bad*/ copy st)
+        fn ident_of(&self, st: &str) -> ast::ident {
+            self.parse_sess.interner.intern(st)
         }
     }
     let imp: @CtxtRepr = @CtxtRepr {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 3097cb799a2..3bfb93b34b3 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -502,10 +502,10 @@ pub fn mk_unreachable(cx: @ext_ctxt, span: span) -> @ast::expr {
         cx,
         span,
         ~[
-            cx.ident_of(~"core"),
-            cx.ident_of(~"sys"),
-            cx.ident_of(~"FailWithCause"),
-            cx.ident_of(~"fail_with"),
+            cx.ident_of("core"),
+            cx.ident_of("sys"),
+            cx.ident_of("FailWithCause"),
+            cx.ident_of("fail_with"),
         ],
         ~[
             mk_base_str(cx, span, ~"internal error: entered unreachable code"),
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 55e25e69936..96e5e414322 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -33,7 +33,7 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
             }
         }
     }
-    let res = cx.parse_sess().interner.intern(@res_str);
+    let res = cx.parse_sess().interner.intern(res_str);
 
     let e = @ast::expr {
         id: cx.next_id(),
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 5998fc7145d..a9234c858f4 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -58,9 +58,9 @@ fn cs_ord(less: bool, equal: bool,
           cx: @ext_ctxt, span: span,
           substr: &Substructure) -> @expr {
     let binop = if less {
-        cx.ident_of(~"lt")
+        cx.ident_of("lt")
     } else {
-        cx.ident_of(~"gt")
+        cx.ident_of("gt")
     };
     let false_blk_expr = build::mk_block(cx, span,
                                          ~[], ~[],
@@ -101,7 +101,7 @@ fn cs_ord(less: bool, equal: bool,
             }
 
             let cmp = build::mk_method_call(cx, span,
-                                            self_f, cx.ident_of(~"eq"), other_fs.to_owned());
+                                            self_f, cx.ident_of("eq"), other_fs.to_owned());
             let subexpr = build::mk_simple_block(cx, span, subexpr);
             let elseif = expr_if(cmp, subexpr, Some(false_blk_expr));
             let elseif = build::mk_expr(cx, span, elseif);
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index ac873c5bd12..7d560a197d0 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -43,21 +43,21 @@ pub fn expand_deriving_totalord(cx: @ext_ctxt,
 
 pub fn ordering_const(cx: @ext_ctxt, span: span, cnst: Ordering) -> @expr {
     let cnst = match cnst {
-        Less => ~"Less",
-        Equal => ~"Equal",
-        Greater => ~"Greater"
+        Less => "Less",
+        Equal => "Equal",
+        Greater => "Greater"
     };
     build::mk_path_global(cx, span,
-                          ~[cx.ident_of(~"core"),
-                            cx.ident_of(~"cmp"),
+                          ~[cx.ident_of("core"),
+                            cx.ident_of("cmp"),
                             cx.ident_of(cnst)])
 }
 
 pub fn cs_cmp(cx: @ext_ctxt, span: span,
               substr: &Substructure) -> @expr {
-    let lexical_ord = ~[cx.ident_of(~"core"),
-                        cx.ident_of(~"cmp"),
-                        cx.ident_of(~"lexical_ordering")];
+    let lexical_ord = ~[cx.ident_of("core"),
+                        cx.ident_of("cmp"),
+                        cx.ident_of("lexical_ordering")];
 
     cs_same_method_fold(
         // foldr (possibly) nests the matches in lexical_ordering better
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index 2bdfe51c50e..fd5d26a1787 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -41,15 +41,15 @@ fn create_derived_decodable_impl(
 ) -> @item {
     let decoder_ty_param = build::mk_ty_param(
         cx,
-        cx.ident_of(~"__D"),
+        cx.ident_of("__D"),
         @opt_vec::with(
             build::mk_trait_ty_param_bound_global(
                 cx,
                 span,
                 ~[
-                    cx.ident_of(~"std"),
-                    cx.ident_of(~"serialize"),
-                    cx.ident_of(~"Decoder"),
+                    cx.ident_of("std"),
+                    cx.ident_of("serialize"),
+                    cx.ident_of("Decoder"),
                 ]
             )
         )
@@ -62,13 +62,13 @@ fn create_derived_decodable_impl(
     let trait_path = build::mk_raw_path_global_(
         span,
         ~[
-            cx.ident_of(~"std"),
-            cx.ident_of(~"serialize"),
-            cx.ident_of(~"Decodable")
+            cx.ident_of("std"),
+            cx.ident_of("serialize"),
+            cx.ident_of("Decodable")
         ],
         None,
         ~[
-            build::mk_simple_ty_path(cx, span, cx.ident_of(~"__D"))
+            build::mk_simple_ty_path(cx, span, cx.ident_of("__D"))
         ]
     );
     create_derived_impl(
@@ -96,11 +96,11 @@ fn create_decode_method(
     let d_arg_type = build::mk_ty_rptr(
         cx,
         span,
-        build::mk_simple_ty_path(cx, span, cx.ident_of(~"__D")),
+        build::mk_simple_ty_path(cx, span, cx.ident_of("__D")),
         None,
         ast::m_mutbl
     );
-    let d_ident = cx.ident_of(~"__d");
+    let d_ident = cx.ident_of("__d");
     let d_arg = build::mk_arg(cx, span, d_ident, d_arg_type);
 
     // Create the type of the return value.
@@ -120,7 +120,7 @@ fn create_decode_method(
 
     // Create the method.
     let self_ty = spanned { node: sty_static, span: span };
-    let method_ident = cx.ident_of(~"decode");
+    let method_ident = cx.ident_of("decode");
     @ast::method {
         ident: method_ident,
         attrs: ~[],
@@ -148,14 +148,14 @@ fn call_substructure_decode_method(
             cx,
             span,
             ~[
-                cx.ident_of(~"std"),
-                cx.ident_of(~"serialize"),
-                cx.ident_of(~"Decodable"),
-                cx.ident_of(~"decode"),
+                cx.ident_of("std"),
+                cx.ident_of("serialize"),
+                cx.ident_of("Decodable"),
+                cx.ident_of("decode"),
             ]
         ),
         ~[
-            build::mk_path(cx, span, ~[cx.ident_of(~"__d")])
+            build::mk_path(cx, span, ~[cx.ident_of("__d")])
         ]
     )
 }
@@ -223,14 +223,14 @@ fn create_read_struct_field(
 
     let d_arg = build::mk_arg(cx,
                               span,
-                              cx.ident_of(~"__d"),
+                              cx.ident_of("__d"),
                               build::mk_ty_infer(cx, span));
 
     let call_expr = build::mk_method_call(
         cx,
         span,
-        build::mk_path(cx, span, ~[cx.ident_of(~"__d")]),
-        cx.ident_of(~"read_struct_field"),
+        build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+        cx.ident_of("read_struct_field"),
         ~[
             build::mk_base_str(cx, span, cx.str_of(ident)),
             build::mk_uint(cx, span, idx),
@@ -257,8 +257,8 @@ fn create_read_struct_arg(
     let call_expr = build::mk_method_call(
         cx,
         span,
-        build::mk_path(cx, span, ~[cx.ident_of(~"__d")]),
-        cx.ident_of(~"read_struct_arg"),
+        build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+        cx.ident_of("read_struct_arg"),
         ~[
             build::mk_uint(cx, span, idx),
             build::mk_lambda_no_args(cx, span, decode_expr),
@@ -295,7 +295,7 @@ fn expand_deriving_decodable_struct_method(
 
     let d_arg = build::mk_arg(cx,
                               span,
-                              cx.ident_of(~"__d"),
+                              cx.ident_of("__d"),
                               build::mk_ty_infer(cx, span));
 
     let read_struct_expr = build::mk_method_call(
@@ -304,9 +304,9 @@ fn expand_deriving_decodable_struct_method(
         build::mk_path(
             cx,
             span,
-            ~[cx.ident_of(~"__d")]
+            ~[cx.ident_of("__d")]
         ),
-        cx.ident_of(~"read_struct"),
+        cx.ident_of("read_struct"),
         ~[
             build::mk_base_str(cx, span, cx.str_of(type_ident)),
             build::mk_uint(cx, span, fields.len()),
@@ -353,15 +353,15 @@ fn create_read_variant_arg(
 
             let d_arg = build::mk_arg(cx,
                                       span,
-                                      cx.ident_of(~"__d"),
+                                      cx.ident_of("__d"),
                                       build::mk_ty_infer(cx, span));
             let t_infer = build::mk_ty_infer(cx, span);
 
             let call_expr = build::mk_method_call(
                 cx,
                 span,
-                build::mk_path(cx, span, ~[cx.ident_of(~"__d")]),
-                cx.ident_of(~"read_enum_variant_arg"),
+                build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+                cx.ident_of("read_enum_variant_arg"),
                 ~[
                     build::mk_uint(cx, span, j),
                     build::mk_lambda(cx,
@@ -416,8 +416,8 @@ fn create_read_enum_variant(
     build::mk_method_call(
         cx,
         span,
-        build::mk_path(cx, span, ~[cx.ident_of(~"__d")]),
-        cx.ident_of(~"read_enum_variant"),
+        build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+        cx.ident_of("read_enum_variant"),
         ~[
             expr_arm_names,
             build::mk_lambda(
@@ -428,13 +428,13 @@ fn create_read_enum_variant(
                         build::mk_arg(
                             cx,
                             span,
-                            cx.ident_of(~"__d"),
+                            cx.ident_of("__d"),
                             build::mk_ty_infer(cx, span)
                         ),
                         build::mk_arg(
                             cx,
                             span,
-                            cx.ident_of(~"__i"),
+                            cx.ident_of("__i"),
                             build::mk_ty_infer(cx, span)
                         )
                     ],
@@ -444,7 +444,7 @@ fn create_read_enum_variant(
                     cx,
                     span,
                     ast::expr_match(
-                        build::mk_path(cx, span, ~[cx.ident_of(~"__i")]),
+                        build::mk_path(cx, span, ~[cx.ident_of("__i")]),
                         arms
                     )
                 )
@@ -468,15 +468,15 @@ fn expand_deriving_decodable_enum_method(
 
     let d_arg = build::mk_arg(cx,
                               span,
-                              cx.ident_of(~"__d"),
+                              cx.ident_of("__d"),
                               build::mk_ty_infer(cx, span));
 
     // Create the read_enum expression
     let read_enum_expr = build::mk_method_call(
         cx,
         span,
-        build::mk_path(cx, span, ~[cx.ident_of(~"__d")]),
-        cx.ident_of(~"read_enum"),
+        build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+        cx.ident_of("read_enum"),
         ~[
             build::mk_base_str(cx, span, cx.str_of(type_ident)),
             build::mk_lambda(cx,
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 54e5687f415..2786c9c6eb5 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -41,15 +41,15 @@ fn create_derived_encodable_impl(
 ) -> @item {
     let encoder_ty_param = build::mk_ty_param(
         cx,
-        cx.ident_of(~"__E"),
+        cx.ident_of("__E"),
         @opt_vec::with(
             build::mk_trait_ty_param_bound_global(
                 cx,
                 span,
                 ~[
-                    cx.ident_of(~"std"),
-                    cx.ident_of(~"serialize"),
-                    cx.ident_of(~"Encoder"),
+                    cx.ident_of("std"),
+                    cx.ident_of("serialize"),
+                    cx.ident_of("Encoder"),
                 ]
             )
         )
@@ -62,13 +62,13 @@ fn create_derived_encodable_impl(
     let trait_path = build::mk_raw_path_global_(
         span,
         ~[
-            cx.ident_of(~"std"),
-            cx.ident_of(~"serialize"),
-            cx.ident_of(~"Encodable")
+            cx.ident_of("std"),
+            cx.ident_of("serialize"),
+            cx.ident_of("Encodable")
         ],
         None,
         ~[
-            build::mk_simple_ty_path(cx, span, cx.ident_of(~"__E"))
+            build::mk_simple_ty_path(cx, span, cx.ident_of("__E"))
         ]
     );
     create_derived_impl(
@@ -94,11 +94,11 @@ fn create_encode_method(
     let e_arg_type = build::mk_ty_rptr(
         cx,
         span,
-        build::mk_simple_ty_path(cx, span, cx.ident_of(~"__E")),
+        build::mk_simple_ty_path(cx, span, cx.ident_of("__E")),
         None,
         ast::m_mutbl
     );
-    let e_arg = build::mk_arg(cx, span, cx.ident_of(~"__e"), e_arg_type);
+    let e_arg = build::mk_arg(cx, span, cx.ident_of("__e"), e_arg_type);
 
     // Create the type of the return value.
     let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span };
@@ -112,7 +112,7 @@ fn create_encode_method(
 
     // Create the method.
     let self_ty = spanned { node: sty_region(None, m_imm), span: span };
-    let method_ident = cx.ident_of(~"encode");
+    let method_ident = cx.ident_of("encode");
     @ast::method {
         ident: method_ident,
         attrs: ~[],
@@ -134,11 +134,11 @@ fn call_substructure_encode_method(
     self_field: @expr
 ) -> @ast::expr {
     // Gather up the parameters we want to chain along.
-    let e_ident = cx.ident_of(~"__e");
+    let e_ident = cx.ident_of("__e");
     let e_expr = build::mk_path(cx, span, ~[e_ident]);
 
     // Call the substructure method.
-    let encode_ident = cx.ident_of(~"encode");
+    let encode_ident = cx.ident_of("encode");
     build::mk_method_call(
         cx,
         span,
@@ -204,7 +204,7 @@ fn expand_deriving_encodable_struct_method(
     type_ident: ident,
     struct_def: &struct_def
 ) -> @method {
-    let self_ident = cx.ident_of(~"self");
+    let self_ident = cx.ident_of("self");
 
     // Create the body of the method.
     let mut idx = 0;
@@ -227,7 +227,7 @@ fn expand_deriving_encodable_struct_method(
                     self_field
                 );
 
-                let e_ident = cx.ident_of(~"__e");
+                let e_ident = cx.ident_of("__e");
                 let e_arg = build::mk_arg(cx,
                                           span,
                                           e_ident,
@@ -243,8 +243,8 @@ fn expand_deriving_encodable_struct_method(
                 let call_expr = build::mk_method_call(
                     cx,
                     span,
-                    build::mk_path(cx, span, ~[cx.ident_of(~"__e")]),
-                    cx.ident_of(~"emit_struct_field"),
+                    build::mk_path(cx, span, ~[cx.ident_of("__e")]),
+                    cx.ident_of("emit_struct_field"),
                     ~[
                         build::mk_base_str(cx, span, cx.str_of(ident)),
                         build::mk_uint(cx, span, idx),
@@ -266,7 +266,7 @@ fn expand_deriving_encodable_struct_method(
 
     let e_arg = build::mk_arg(cx,
                               span,
-                              cx.ident_of(~"__e"),
+                              cx.ident_of("__e"),
                               build::mk_ty_infer(cx, span));
 
     let emit_struct_stmt = build::mk_method_call(
@@ -275,9 +275,9 @@ fn expand_deriving_encodable_struct_method(
         build::mk_path(
             cx,
             span,
-            ~[cx.ident_of(~"__e")]
+            ~[cx.ident_of("__e")]
         ),
-        cx.ident_of(~"emit_struct"),
+        cx.ident_of("emit_struct"),
         ~[
             build::mk_base_str(cx, span, cx.str_of(type_ident)),
             build::mk_uint(cx, span, statements.len()),
@@ -305,7 +305,7 @@ fn expand_deriving_encodable_enum_method(
     // Create the arms of the match in the method body.
     let arms = do enum_definition.variants.mapi |i, variant| {
         // Create the matching pattern.
-        let (pat, fields) = create_enum_variant_pattern(cx, span, variant, ~"__self", ast::m_imm);
+        let (pat, fields) = create_enum_variant_pattern(cx, span, variant, "__self", ast::m_imm);
 
         // Feed the discriminant to the encode function.
         let mut stmts = ~[];
@@ -317,7 +317,7 @@ fn expand_deriving_encodable_enum_method(
             // Call the substructure method.
             let expr = call_substructure_encode_method(cx, span, field);
 
-            let e_ident = cx.ident_of(~"__e");
+            let e_ident = cx.ident_of("__e");
             let e_arg = build::mk_arg(cx,
                                       span,
                                       e_ident,
@@ -333,8 +333,8 @@ fn expand_deriving_encodable_enum_method(
             let call_expr = build::mk_method_call(
                 cx,
                 span,
-                build::mk_path(cx, span, ~[cx.ident_of(~"__e")]),
-                cx.ident_of(~"emit_enum_variant_arg"),
+                build::mk_path(cx, span, ~[cx.ident_of("__e")]),
+                cx.ident_of("emit_enum_variant_arg"),
                 ~[
                     build::mk_uint(cx, span, j),
                     blk_expr,
@@ -347,13 +347,13 @@ fn expand_deriving_encodable_enum_method(
         // Create the pattern body.
         let e_arg = build::mk_arg(cx,
                                   span,
-                                  cx.ident_of(~"__e"),
+                                  cx.ident_of("__e"),
                                   build::mk_ty_infer(cx, span));
         let call_expr = build::mk_method_call(
             cx,
             span,
-            build::mk_path(cx, span, ~[cx.ident_of(~"__e")]),
-            cx.ident_of(~"emit_enum_variant"),
+            build::mk_path(cx, span, ~[cx.ident_of("__e")]),
+            cx.ident_of("emit_enum_variant"),
             ~[
                 build::mk_base_str(cx, span, cx.str_of(variant.node.name)),
                 build::mk_uint(cx, span, i),
@@ -377,7 +377,7 @@ fn expand_deriving_encodable_enum_method(
         }
     };
 
-    let e_ident = cx.ident_of(~"__e");
+    let e_ident = cx.ident_of("__e");
     let e_arg = build::mk_arg(cx,
                               span,
                               e_ident,
@@ -394,8 +394,8 @@ fn expand_deriving_encodable_enum_method(
     let call_expr = build::mk_method_call(
         cx,
         span,
-        build::mk_path(cx, span, ~[cx.ident_of(~"__e")]),
-        cx.ident_of(~"emit_enum"),
+        build::mk_path(cx, span, ~[cx.ident_of("__e")]),
+        cx.ident_of("emit_enum"),
         ~[
             build::mk_base_str(cx, span, cx.str_of(type_ident)),
             lambda_expr,
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 2bd45e1466c..78eacafe3d7 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -263,7 +263,7 @@ pub fn create_struct_pattern(cx: @ext_ctxt,
                              span: span,
                              struct_ident: ident,
                              struct_def: &struct_def,
-                             prefix: ~str,
+                             prefix: &str,
                              mutbl: ast::mutability)
     -> (@ast::pat, ~[(Option<ident>, @expr)]) {
     if struct_def.fields.is_empty() {
@@ -323,7 +323,7 @@ pub fn create_struct_pattern(cx: @ext_ctxt,
 pub fn create_enum_variant_pattern(cx: @ext_ctxt,
                                    span: span,
                                    variant: &ast::variant,
-                                   prefix: ~str,
+                                   prefix: &str,
                                    mutbl: ast::mutability)
     -> (@ast::pat, ~[(Option<ident>, @expr)]) {
 
@@ -371,7 +371,7 @@ pub fn expand_enum_or_struct_match(cx: @ext_ctxt,
                                span: span,
                                arms: ~[ ast::arm ])
                             -> @expr {
-    let self_ident = cx.ident_of(~"self");
+    let self_ident = cx.ident_of("self");
     let self_expr = build::mk_path(cx, span, ~[ self_ident ]);
     let self_expr = build::mk_unary(cx, span, ast::deref, self_expr);
     let self_match_expr = ast::expr_match(self_expr, arms);
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index 604686f442f..9030be86f39 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -53,10 +53,10 @@ fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr
         _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
     };
     let rand_ident = ~[
-        cx.ident_of(~"core"),
-        cx.ident_of(~"rand"),
-        cx.ident_of(~"Rand"),
-        cx.ident_of(~"rand")
+        cx.ident_of("core"),
+        cx.ident_of("rand"),
+        cx.ident_of("Rand"),
+        cx.ident_of("rand")
     ];
     let rand_call = || {
         build::mk_call_global(cx,
@@ -77,8 +77,8 @@ fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr
             let variant_count = build::mk_uint(cx, span, variants.len());
 
             // need to specify the uint-ness of the random number
-            let u32_ty = build::mk_ty_path(cx, span, ~[cx.ident_of(~"uint")]);
-            let r_ty = build::mk_ty_path(cx, span, ~[cx.ident_of(~"R")]);
+            let u32_ty = build::mk_ty_path(cx, span, ~[cx.ident_of("uint")]);
+            let r_ty = build::mk_ty_path(cx, span, ~[cx.ident_of("R")]);
             let rand_name = build::mk_raw_path_(span, copy rand_ident, None, ~[ u32_ty, r_ty ]);
             let rand_name = build::mk_path_raw(cx, span, rand_name);
 
diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs
index 2c7d449585f..6010354349e 100644
--- a/src/libsyntax/ext/deriving/to_str.rs
+++ b/src/libsyntax/ext/deriving/to_str.rs
@@ -44,11 +44,11 @@ fn to_str_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @exp
         [self_obj] => {
             let self_addr = build::mk_addr_of(cx, span, self_obj);
             build::mk_call_global(cx, span,
-                                  ~[cx.ident_of(~"core"),
-                                    cx.ident_of(~"sys"),
-                                    cx.ident_of(~"log_str")],
+                                  ~[cx.ident_of("core"),
+                                    cx.ident_of("sys"),
+                                    cx.ident_of("log_str")],
                                   ~[self_addr])
         }
         _ => cx.span_bug(span, ~"Invalid number of arguments in `deriving(ToStr)`")
     }
-}
\ No newline at end of file
+}
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
index 6195a3a6424..08947efa7b7 100644
--- a/src/libsyntax/ext/deriving/ty.rs
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -218,7 +218,7 @@ pub impl LifetimeBounds {
 
 pub fn get_explicit_self(cx: @ext_ctxt, span: span, self_ptr: Option<PtrTy>)
     -> (@expr, ast::self_ty) {
-    let self_path = build::mk_path(cx, span, ~[cx.ident_of(~"self")]);
+    let self_path = build::mk_path(cx, span, ~[cx.ident_of("self")]);
     match self_ptr {
         None => {
             (self_path, respan(span, ast::sty_value))
diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs
index e9eebe5b2ac..1a8edec3714 100644
--- a/src/libsyntax/ext/fmt.rs
+++ b/src/libsyntax/ext/fmt.rs
@@ -49,12 +49,12 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
 fn pieces_to_expr(cx: @ext_ctxt, sp: span,
                   pieces: ~[Piece], args: ~[@ast::expr])
    -> @ast::expr {
-    fn make_path_vec(cx: @ext_ctxt, ident: @~str) -> ~[ast::ident] {
+    fn make_path_vec(cx: @ext_ctxt, ident: &str) -> ~[ast::ident] {
         let intr = cx.parse_sess().interner;
-        return ~[intr.intern(@~"unstable"), intr.intern(@~"extfmt"),
-                 intr.intern(@~"rt"), intr.intern(ident)];
+        return ~[intr.intern("unstable"), intr.intern("extfmt"),
+                 intr.intern("rt"), intr.intern(ident)];
     }
-    fn make_rt_path_expr(cx: @ext_ctxt, sp: span, nm: @~str) -> @ast::expr {
+    fn make_rt_path_expr(cx: @ext_ctxt, sp: span, nm: &str) -> @ast::expr {
         let path = make_path_vec(cx, nm);
         return mk_path_global(cx, sp, path);
     }
@@ -63,28 +63,28 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
 
     fn make_rt_conv_expr(cx: @ext_ctxt, sp: span, cnv: &Conv) -> @ast::expr {
         fn make_flags(cx: @ext_ctxt, sp: span, flags: ~[Flag]) -> @ast::expr {
-            let mut tmp_expr = make_rt_path_expr(cx, sp, @~"flag_none");
+            let mut tmp_expr = make_rt_path_expr(cx, sp, "flag_none");
             for flags.each |f| {
                 let fstr = match *f {
-                  FlagLeftJustify => ~"flag_left_justify",
-                  FlagLeftZeroPad => ~"flag_left_zero_pad",
-                  FlagSpaceForSign => ~"flag_space_for_sign",
-                  FlagSignAlways => ~"flag_sign_always",
-                  FlagAlternate => ~"flag_alternate"
+                  FlagLeftJustify => "flag_left_justify",
+                  FlagLeftZeroPad => "flag_left_zero_pad",
+                  FlagSpaceForSign => "flag_space_for_sign",
+                  FlagSignAlways => "flag_sign_always",
+                  FlagAlternate => "flag_alternate"
                 };
                 tmp_expr = mk_binary(cx, sp, ast::bitor, tmp_expr,
-                                     make_rt_path_expr(cx, sp, @fstr));
+                                     make_rt_path_expr(cx, sp, fstr));
             }
             return tmp_expr;
         }
         fn make_count(cx: @ext_ctxt, sp: span, cnt: Count) -> @ast::expr {
             match cnt {
               CountImplied => {
-                return make_rt_path_expr(cx, sp, @~"CountImplied");
+                return make_rt_path_expr(cx, sp, "CountImplied");
               }
               CountIs(c) => {
                 let count_lit = mk_uint(cx, sp, c as uint);
-                let count_is_path = make_path_vec(cx, @~"CountIs");
+                let count_is_path = make_path_vec(cx, "CountIs");
                 let count_is_args = ~[count_lit];
                 return mk_call_global(cx, sp, count_is_path, count_is_args);
               }
@@ -92,17 +92,16 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
             }
         }
         fn make_ty(cx: @ext_ctxt, sp: span, t: Ty) -> @ast::expr {
-            let rt_type;
-            match t {
+            let rt_type = match t {
               TyHex(c) => match c {
-                CaseUpper => rt_type = ~"TyHexUpper",
-                CaseLower => rt_type = ~"TyHexLower"
+                CaseUpper =>  "TyHexUpper",
+                CaseLower =>  "TyHexLower"
               },
-              TyBits => rt_type = ~"TyBits",
-              TyOctal => rt_type = ~"TyOctal",
-              _ => rt_type = ~"TyDefault"
-            }
-            return make_rt_path_expr(cx, sp, @rt_type);
+              TyBits =>  "TyBits",
+              TyOctal =>  "TyOctal",
+              _ =>  "TyDefault"
+            };
+            return make_rt_path_expr(cx, sp, rt_type);
         }
         fn make_conv_struct(cx: @ext_ctxt, sp: span, flags_expr: @ast::expr,
                          width_expr: @ast::expr, precision_expr: @ast::expr,
@@ -111,19 +110,19 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
             mk_global_struct_e(
                 cx,
                 sp,
-                make_path_vec(cx, @~"Conv"),
+                make_path_vec(cx, "Conv"),
                 ~[
                     build::Field {
-                        ident: intr.intern(@~"flags"), ex: flags_expr
+                        ident: intr.intern("flags"), ex: flags_expr
                     },
                     build::Field {
-                        ident: intr.intern(@~"width"), ex: width_expr
+                        ident: intr.intern("width"), ex: width_expr
                     },
                     build::Field {
-                        ident: intr.intern(@~"precision"), ex: precision_expr
+                        ident: intr.intern("precision"), ex: precision_expr
                     },
                     build::Field {
-                        ident: intr.intern(@~"ty"), ex: ty_expr
+                        ident: intr.intern("ty"), ex: ty_expr
                     },
                 ]
             )
@@ -138,7 +137,7 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
     fn make_conv_call(cx: @ext_ctxt, sp: span, conv_type: &str, cnv: &Conv,
                       arg: @ast::expr, buf: @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, buf];
         return mk_call_global(cx, arg.span, path, args);
@@ -259,10 +258,10 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
     let nargs = args.len();
 
     /* 'ident' is the local buffer building up the result of fmt! */
-    let ident = cx.parse_sess().interner.intern(@~"__fmtbuf");
+    let ident = cx.parse_sess().interner.intern("__fmtbuf");
     let buf = || mk_path(cx, fmt_sp, ~[ident]);
-    let str_ident = cx.parse_sess().interner.intern(@~"str");
-    let push_ident = cx.parse_sess().interner.intern(@~"push_str");
+    let str_ident = cx.parse_sess().interner.intern("str");
+    let push_ident = cx.parse_sess().interner.intern("push_str");
     let mut stms = ~[];
 
     /* Translate each piece (portion of the fmt expression) by invoking the
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index deaf1b1c754..a5148287258 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -138,9 +138,9 @@ pub trait ext_ctxt_ast_builder {
 impl ext_ctxt_ast_builder for @ext_ctxt {
     fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty {
         self.ty_path_ast_builder(path_global(~[
-            self.ident_of(~"core"),
-            self.ident_of(~"option"),
-            self.ident_of(~"Option")
+            self.ident_of("core"),
+            self.ident_of("option"),
+            self.ident_of("Option")
         ], dummy_sp()).add_ty(ty))
     }
 
@@ -360,12 +360,12 @@ impl ext_ctxt_ast_builder for @ext_ctxt {
         let vi = ast::view_item_use(~[
             @codemap::spanned {
                 node: ast::view_path_simple(
-                    self.ident_of(~"Owned"),
+                    self.ident_of("Owned"),
                     path(
                         ~[
-                            self.ident_of(~"core"),
-                            self.ident_of(~"kinds"),
-                            self.ident_of(~"Owned")
+                            self.ident_of("core"),
+                            self.ident_of("kinds"),
+                            self.ident_of("Owned")
                         ],
                         codemap::dummy_sp()
                     ),
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 7ac3ea4789d..b537ef87d54 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -58,7 +58,7 @@ impl gen_send for message {
                 path(~[this.data_name()], span)
                 .add_tys(cx.ty_vars_global(&this.generics.ty_params)));
             let args_ast = vec::append(
-                ~[cx.arg(cx.ident_of(~"pipe"),
+                ~[cx.arg(cx.ident_of("pipe"),
                               pipe_ty)],
                 args_ast);
 
@@ -136,7 +136,7 @@ impl gen_send for message {
                 };
 
                 let args_ast = vec::append(
-                    ~[cx.arg(cx.ident_of(~"pipe"),
+                    ~[cx.arg(cx.ident_of("pipe"),
                              cx.ty_path_ast_builder(
                                  path(~[this.data_name()], span)
                                  .add_tys(cx.ty_vars_global(
@@ -212,8 +212,8 @@ impl to_type_decls for state {
                 let next_name = cx.str_of(next.data_name());
 
                 let dir = match this.dir {
-                  send => ~"server",
-                  recv => ~"client"
+                  send => "server",
+                  recv => "client"
                 };
 
                 vec::append_one(tys,
@@ -265,12 +265,12 @@ impl to_type_decls for state {
                     self.data_name(),
                     self.span,
                     cx.ty_path_ast_builder(
-                        path_global(~[cx.ident_of(~"core"),
-                                      cx.ident_of(~"pipes"),
-                                      cx.ident_of(dir.to_str() + ~"Packet")],
+                        path_global(~[cx.ident_of("core"),
+                                      cx.ident_of("pipes"),
+                                      cx.ident_of(dir.to_str() + "Packet")],
                              dummy_sp())
                         .add_ty(cx.ty_path_ast_builder(
-                            path(~[cx.ident_of(~"super"),
+                            path(~[cx.ident_of("super"),
                                    self.data_name()],
                                  dummy_sp())
                             .add_tys(cx.ty_vars_global(
@@ -283,13 +283,13 @@ impl to_type_decls for state {
                     self.data_name(),
                     self.span,
                     cx.ty_path_ast_builder(
-                        path_global(~[cx.ident_of(~"core"),
-                                      cx.ident_of(~"pipes"),
+                        path_global(~[cx.ident_of("core"),
+                                      cx.ident_of("pipes"),
                                       cx.ident_of(dir.to_str()
-                                                  + ~"PacketBuffered")],
+                                                  + "PacketBuffered")],
                              dummy_sp())
                         .add_tys(~[cx.ty_path_ast_builder(
-                            path(~[cx.ident_of(~"super"),
+                            path(~[cx.ident_of("super"),
                                    self.data_name()],
                                         dummy_sp())
                             .add_tys(cx.ty_vars_global(
@@ -341,7 +341,7 @@ impl gen_init for protocol {
     }
 
     fn gen_buffer_init(&self, ext_cx: @ext_ctxt) -> @ast::expr {
-        ext_cx.struct_expr(path(~[ext_cx.ident_of(~"__Buffer")],
+        ext_cx.struct_expr(path(~[ext_cx.ident_of("__Buffer")],
                                 dummy_sp()),
                       self.states.map_to_vec(|s| {
             let fty = s.to_ty(ext_cx);
@@ -389,8 +389,8 @@ impl gen_init for protocol {
             }
         }
 
-        cx.ty_path_ast_builder(path(~[cx.ident_of(~"super"),
-                                      cx.ident_of(~"__Buffer")],
+        cx.ty_path_ast_builder(path(~[cx.ident_of("super"),
+                                      cx.ident_of("__Buffer")],
                                     copy self.span)
                                .add_tys(cx.ty_vars_global(&params)))
     }
@@ -427,7 +427,7 @@ impl gen_init for protocol {
         };
 
         cx.item_struct_poly(
-            cx.ident_of(~"__Buffer"),
+            cx.ident_of("__Buffer"),
             dummy_sp(),
             ast::struct_def {
                 fields: fields,
@@ -452,13 +452,13 @@ impl gen_init for protocol {
             items.push(self.gen_buffer_type(cx))
         }
 
-        items.push(cx.item_mod(cx.ident_of(~"client"),
+        items.push(cx.item_mod(cx.ident_of("client"),
                                copy self.span,
                                client_states));
-        items.push(cx.item_mod(cx.ident_of(~"server"),
+        items.push(cx.item_mod(cx.ident_of("server"),
                                copy self.span,
                                server_states));
 
-        cx.item_mod(cx.ident_of(self.name), copy self.span, items)
+        cx.item_mod(cx.ident_of(copy self.name), copy self.span, items)
     }
 }
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 917d11a0d23..f133347d948 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -377,14 +377,14 @@ pub fn expand_quote_tokens(cx: @ext_ctxt,
 pub fn expand_quote_expr(cx: @ext_ctxt,
                          sp: span,
                          tts: &[ast::token_tree]) -> base::MacResult {
-    base::MRExpr(expand_parse_call(cx, sp, ~"parse_expr", ~[], tts))
+    base::MRExpr(expand_parse_call(cx, sp, "parse_expr", ~[], tts))
 }
 
 pub fn expand_quote_item(cx: @ext_ctxt,
                          sp: span,
                          tts: &[ast::token_tree]) -> base::MacResult {
     let e_attrs = build::mk_uniq_vec_e(cx, sp, ~[]);
-    base::MRExpr(expand_parse_call(cx, sp, ~"parse_item",
+    base::MRExpr(expand_parse_call(cx, sp, "parse_item",
                                     ~[e_attrs], tts))
 }
 
@@ -392,7 +392,7 @@ pub fn expand_quote_pat(cx: @ext_ctxt,
                         sp: span,
                         tts: &[ast::token_tree]) -> base::MacResult {
     let e_refutable = build::mk_lit(cx, sp, ast::lit_bool(true));
-    base::MRExpr(expand_parse_call(cx, sp, ~"parse_pat",
+    base::MRExpr(expand_parse_call(cx, sp, "parse_pat",
                                     ~[e_refutable], tts))
 }
 
@@ -400,7 +400,7 @@ pub fn expand_quote_ty(cx: @ext_ctxt,
                        sp: span,
                        tts: &[ast::token_tree]) -> base::MacResult {
     let e_param_colons = build::mk_lit(cx, sp, ast::lit_bool(false));
-    base::MRExpr(expand_parse_call(cx, sp, ~"parse_ty",
+    base::MRExpr(expand_parse_call(cx, sp, "parse_ty",
                                     ~[e_param_colons], tts))
 }
 
@@ -408,16 +408,16 @@ pub fn expand_quote_stmt(cx: @ext_ctxt,
                          sp: span,
                          tts: &[ast::token_tree]) -> base::MacResult {
     let e_attrs = build::mk_uniq_vec_e(cx, sp, ~[]);
-    base::MRExpr(expand_parse_call(cx, sp, ~"parse_stmt",
+    base::MRExpr(expand_parse_call(cx, sp, "parse_stmt",
                                     ~[e_attrs], tts))
 }
 
 fn ids_ext(cx: @ext_ctxt, strs: ~[~str]) -> ~[ast::ident] {
-    strs.map(|str| cx.parse_sess().interner.intern(@copy *str))
+    strs.map(|str| cx.parse_sess().interner.intern(*str))
 }
 
-fn id_ext(cx: @ext_ctxt, str: ~str) -> ast::ident {
-    cx.parse_sess().interner.intern(@str)
+fn id_ext(cx: @ext_ctxt, str: &str) -> ast::ident {
+    cx.parse_sess().interner.intern(str)
 }
 
 // Lift an ident to the expr that evaluates to that ident.
@@ -425,7 +425,7 @@ fn mk_ident(cx: @ext_ctxt, sp: span, ident: ast::ident) -> @ast::expr {
     let e_str = build::mk_uniq_str(cx, sp, cx.str_of(ident));
     build::mk_method_call(cx, sp,
                           build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
-                          id_ext(cx, ~"ident_of"),
+                          id_ext(cx, "ident_of"),
                           ~[e_str])
 }
 
@@ -616,7 +616,7 @@ fn mk_tt(cx: @ext_ctxt, sp: span, tt: &ast::token_tree)
             let e_push =
                 build::mk_method_call(cx, sp,
                                       build::mk_path(cx, sp, ids_ext(cx, ~[~"tt"])),
-                                      id_ext(cx, ~"push"),
+                                      id_ext(cx, "push"),
                                       ~[e_tok]);
             ~[build::mk_stmt(cx, sp, e_push)]
 
@@ -632,14 +632,14 @@ fn mk_tt(cx: @ext_ctxt, sp: span, tt: &ast::token_tree)
             let e_to_toks =
                 build::mk_method_call(cx, sp,
                                       build::mk_path(cx, sp, ~[ident]),
-                                      id_ext(cx, ~"to_tokens"),
+                                      id_ext(cx, "to_tokens"),
                                       ~[build::mk_path(cx, sp,
                                                        ids_ext(cx, ~[~"ext_cx"]))]);
 
             let e_push =
                 build::mk_method_call(cx, sp,
                                       build::mk_path(cx, sp, ids_ext(cx, ~[~"tt"])),
-                                      id_ext(cx, ~"push_all_move"),
+                                      id_ext(cx, "push_all_move"),
                                       ~[e_to_toks]);
 
             ~[build::mk_stmt(cx, sp, e_push)]
@@ -711,15 +711,15 @@ fn expand_tts(cx: @ext_ctxt,
 
     let e_sp = build::mk_method_call(cx, sp,
                                      build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
-                                     id_ext(cx, ~"call_site"),
+                                     id_ext(cx, "call_site"),
                                      ~[]);
 
     let stmt_let_sp = build::mk_local(cx, sp, false,
-                                      id_ext(cx, ~"sp"),
+                                      id_ext(cx, "sp"),
                                       e_sp);
 
     let stmt_let_tt = build::mk_local(cx, sp, true,
-                                      id_ext(cx, ~"tt"),
+                                      id_ext(cx, "tt"),
                                       build::mk_uniq_vec_e(cx, sp, ~[]));
 
     build::mk_block(cx, sp, uses,
@@ -731,18 +731,18 @@ fn expand_tts(cx: @ext_ctxt,
 
 fn expand_parse_call(cx: @ext_ctxt,
                      sp: span,
-                     parse_method: ~str,
+                     parse_method: &str,
                      arg_exprs: ~[@ast::expr],
                      tts: &[ast::token_tree]) -> @ast::expr {
     let tts_expr = expand_tts(cx, sp, tts);
 
     let cfg_call = || build::mk_method_call(
         cx, sp, build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
-        id_ext(cx, ~"cfg"), ~[]);
+        id_ext(cx, "cfg"), ~[]);
 
     let parse_sess_call = || build::mk_method_call(
         cx, sp, build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
-        id_ext(cx, ~"parse_sess"), ~[]);
+        id_ext(cx, "parse_sess"), ~[]);
 
     let new_parser_call =
         build::mk_call_global(cx, sp,
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 39c3c63a9b7..fc00fd12848 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -36,8 +36,8 @@ pub fn add_new_extension(cx: @ext_ctxt,
         spanned { node: copy m, span: dummy_sp() }
     }
 
-    let lhs_nm =  cx.parse_sess().interner.gensym(@~"lhs");
-    let rhs_nm =  cx.parse_sess().interner.gensym(@~"rhs");
+    let lhs_nm =  cx.parse_sess().interner.gensym("lhs");
+    let rhs_nm =  cx.parse_sess().interner.gensym("rhs");
 
     // The grammar for macro_rules! is:
     // $( $lhs:mtcs => $rhs:tt );+
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 8956622a06b..764dec0eeb3 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -271,7 +271,7 @@ fn consume_any_line_comment(rdr: @mut StringReader)
                 // but comments with only "/"s are not
                 if !is_line_non_doc_comment(acc) {
                     return Some(TokenAndSpan{
-                        tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
+                        tok: token::DOC_COMMENT(rdr.interner.intern(acc)),
                         sp: codemap::mk_sp(start_bpos, rdr.pos)
                     });
                 }
@@ -325,7 +325,7 @@ fn consume_block_comment(rdr: @mut StringReader)
             // but comments with only "*"s between two "/"s are not
             if !is_block_non_doc_comment(acc) {
                 return Some(TokenAndSpan{
-                    tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
+                    tok: token::DOC_COMMENT(rdr.interner.intern(acc)),
                     sp: codemap::mk_sp(start_bpos, rdr.pos)
                 });
             }
@@ -467,12 +467,12 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
         if c == '3' && n == '2' {
             bump(rdr);
             bump(rdr);
-            return token::LIT_FLOAT(rdr.interner.intern(@num_str),
+            return token::LIT_FLOAT(rdr.interner.intern(num_str),
                                  ast::ty_f32);
         } else if c == '6' && n == '4' {
             bump(rdr);
             bump(rdr);
-            return token::LIT_FLOAT(rdr.interner.intern(@num_str),
+            return token::LIT_FLOAT(rdr.interner.intern(num_str),
                                  ast::ty_f64);
             /* FIXME (#2252): if this is out of range for either a
             32-bit or 64-bit float, it won't be noticed till the
@@ -484,9 +484,9 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
     }
     if is_float {
         if is_machine_float {
-            return token::LIT_FLOAT(rdr.interner.intern(@num_str), ast::ty_f);
+            return token::LIT_FLOAT(rdr.interner.intern(num_str), ast::ty_f);
         }
-        return token::LIT_FLOAT_UNSUFFIXED(rdr.interner.intern(@num_str));
+        return token::LIT_FLOAT_UNSUFFIXED(rdr.interner.intern(num_str));
     } else {
         if str::len(num_str) == 0u {
             rdr.fatal(~"no valid digits found for number");
@@ -548,7 +548,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
         let is_mod_name = c == ':' && nextch(rdr) == ':';
 
         // FIXME: perform NFKC normalization here. (Issue #2253)
-        return token::IDENT(rdr.interner.intern(@accum_str), is_mod_name);
+        return token::IDENT(rdr.interner.intern(accum_str), is_mod_name);
     }
     if is_dec_digit(c) {
         return scan_number(c, rdr);
@@ -658,7 +658,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
                 lifetime_name.push_char(rdr.curr);
                 bump(rdr);
             }
-            return token::LIFETIME(rdr.interner.intern(@lifetime_name));
+            return token::LIFETIME(rdr.interner.intern(lifetime_name));
         }
 
         // Otherwise it is a character constant:
@@ -731,7 +731,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
             }
         }
         bump(rdr);
-        return token::LIT_STR(rdr.interner.intern(@accum_str));
+        return token::LIT_STR(rdr.interner.intern(accum_str));
       }
       '-' => {
         if nextch(rdr) == '>' {
@@ -799,7 +799,7 @@ mod test {
         let Env {interner: ident_interner, string_reader} =
             setup(~"/* my source file */ \
                     fn main() { io::println(~\"zebra\"); }\n");
-        let id = ident_interner.intern(@~"fn");
+        let id = ident_interner.intern("fn");
         let tok1 = string_reader.next_token();
         let tok2 = TokenAndSpan{
             tok:token::IDENT(id, false),
@@ -810,7 +810,7 @@ mod test {
         // read another token:
         let tok3 = string_reader.next_token();
         let tok4 = TokenAndSpan{
-            tok:token::IDENT(ident_interner.intern (@~"main"), false),
+            tok:token::IDENT(ident_interner.intern("main"), false),
             sp:span {lo:BytePos(24),hi:BytePos(28),expn_info: None}};
         assert_eq!(tok3,tok4);
         // the lparen is already read:
@@ -828,39 +828,39 @@ mod test {
     }
 
     // make the identifier by looking up the string in the interner
-    fn mk_ident (env: Env, id: ~str, is_mod_name: bool) -> token::Token {
-        token::IDENT (env.interner.intern(@id),is_mod_name)
+    fn mk_ident (env: Env, id: &str, is_mod_name: bool) -> token::Token {
+        token::IDENT (env.interner.intern(id),is_mod_name)
     }
 
     #[test] fn doublecolonparsing () {
         let env = setup (~"a b");
         check_tokenization (env,
-                           ~[mk_ident (env,~"a",false),
-                             mk_ident (env,~"b",false)]);
+                           ~[mk_ident (env,"a",false),
+                             mk_ident (env,"b",false)]);
     }
 
     #[test] fn dcparsing_2 () {
         let env = setup (~"a::b");
         check_tokenization (env,
-                           ~[mk_ident (env,~"a",true),
+                           ~[mk_ident (env,"a",true),
                              token::MOD_SEP,
-                             mk_ident (env,~"b",false)]);
+                             mk_ident (env,"b",false)]);
     }
 
     #[test] fn dcparsing_3 () {
         let env = setup (~"a ::b");
         check_tokenization (env,
-                           ~[mk_ident (env,~"a",false),
+                           ~[mk_ident (env,"a",false),
                              token::MOD_SEP,
-                             mk_ident (env,~"b",false)]);
+                             mk_ident (env,"b",false)]);
     }
 
     #[test] fn dcparsing_4 () {
         let env = setup (~"a:: b");
         check_tokenization (env,
-                           ~[mk_ident (env,~"a",true),
+                           ~[mk_ident (env,"a",true),
                              token::MOD_SEP,
-                             mk_ident (env,~"b",false)]);
+                             mk_ident (env,"b",false)]);
     }
 
     #[test] fn character_a() {
@@ -888,7 +888,7 @@ mod test {
         let env = setup(~"'abc");
         let TokenAndSpan {tok, sp: _} =
             env.string_reader.next_token();
-        let id = env.interner.intern(@~"abc");
+        let id = env.interner.intern("abc");
         assert_eq!(tok, token::LIFETIME(id));
     }
 }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 0708b65864e..ce41d377346 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -375,13 +375,13 @@ mod test {
 
         assert!(i.len() < 100);
         for int::range(0,100-((i.len()).to_int())) |_dc| {
-            i.gensym(@~"dontcare");
+            i.gensym("dontcare");
         }
-        i.intern(@~"a");
-        i.intern(@~"b");
-        i.intern(@~"c");
-        i.intern(@~"d");
-        i.intern(@~"return");
+        i.intern("a");
+        i.intern("b");
+        i.intern("c");
+        i.intern("d");
+        i.intern("return");
         assert!(i.get(ast::ident{repr:101,ctxt:0}) == @~"b");
         i
     }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index fe7bd5b3bc1..4483cc42361 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -11,7 +11,7 @@
 use ast;
 use ast_util;
 use parse::token;
-use util::interner::Interner;
+use util::interner::StrInterner;
 use util::interner;
 
 use core::cmp::Equiv;
@@ -390,14 +390,14 @@ pub fn token_to_binop(tok: Token) -> Option<ast::binop> {
 }
 
 pub struct ident_interner {
-    priv interner: Interner<@~str>,
+    priv interner: StrInterner,
 }
 
 pub impl ident_interner {
-    fn intern(&self, val: @~str) -> ast::ident {
+    fn intern(&self, val: &str) -> ast::ident {
         ast::ident { repr: self.interner.intern(val), ctxt: 0 }
     }
-    fn gensym(&self, val: @~str) -> ast::ident {
+    fn gensym(&self, val: &str) -> ast::ident {
         ast::ident { repr: self.interner.gensym(val), ctxt: 0 }
     }
     fn get(&self, idx: ast::ident) -> @~str {
@@ -421,45 +421,45 @@ pub fn mk_fresh_ident_interner() -> @ident_interner {
     // the indices here must correspond to the numbers in
     // special_idents.
     let init_vec = ~[
-        @~"_",                  // 0
-        @~"anon",               // 1
-        @~"",                   // 2
-        @~"unary",              // 3
-        @~"!",                  // 4
-        @~"[]",                 // 5
-        @~"unary-",             // 6
-        @~"__extensions__",     // 7
-        @~"self",               // 8
-        @~"item",               // 9
-        @~"block",              // 10
-        @~"stmt",               // 11
-        @~"pat",                // 12
-        @~"expr",               // 13
-        @~"ty",                 // 14
-        @~"ident",              // 15
-        @~"path",               // 16
-        @~"tt",                 // 17
-        @~"matchers",           // 18
-        @~"str",                // 19
-        @~"TyVisitor",          // 20
-        @~"arg",                // 21
-        @~"descrim",            // 22
-        @~"__rust_abi",         // 23
-        @~"__rust_stack_shim",  // 24
-        @~"TyDesc",             // 25
-        @~"main",               // 26
-        @~"<opaque>",           // 27
-        @~"blk",                // 28
-        @~"static",             // 29
-        @~"intrinsic",          // 30
-        @~"__foreign_mod__",    // 31
-        @~"__field__",          // 32
-        @~"C",                  // 33
-        @~"Self",               // 34
+        "_",                  // 0
+        "anon",               // 1
+        "",                   // 2
+        "unary",              // 3
+        "!",                  // 4
+        "[]",                 // 5
+        "unary-",             // 6
+        "__extensions__",     // 7
+        "self",               // 8
+        "item",               // 9
+        "block",              // 10
+        "stmt",               // 11
+        "pat",                // 12
+        "expr",               // 13
+        "ty",                 // 14
+        "ident",              // 15
+        "path",               // 16
+        "tt",                 // 17
+        "matchers",           // 18
+        "str",                // 19
+        "TyVisitor",          // 20
+        "arg",                // 21
+        "descrim",            // 22
+        "__rust_abi",         // 23
+        "__rust_stack_shim",  // 24
+        "TyDesc",             // 25
+        "main",               // 26
+        "<opaque>",           // 27
+        "blk",                // 28
+        "static",             // 29
+        "intrinsic",          // 30
+        "__foreign_mod__",    // 31
+        "__field__",          // 32
+        "C",                  // 33
+        "Self",               // 34
     ];
 
     let rv = @ident_interner {
-        interner: interner::Interner::prefill(init_vec)
+        interner: interner::StrInterner::prefill(init_vec)
     };
     unsafe {
         task::local_data::local_data_set(interner_key!(), @rv);
@@ -483,7 +483,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::Interner::new() }
+    @ident_interner { interner: interner::StrInterner::new() }
 }
 
 /**
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index f12fb21992e..81652f9c1a1 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -2249,7 +2249,7 @@ mod test {
     #[test]
     fn test_fun_to_str() {
         let mock_interner = parse::token::mk_fake_ident_interner();
-        let abba_ident = mock_interner.intern(@~"abba");
+        let abba_ident = mock_interner.intern("abba");
 
         let decl = ast::fn_decl {
             inputs: ~[],
@@ -2267,7 +2267,7 @@ mod test {
     #[test]
     fn test_variant_to_str() {
         let mock_interner = parse::token::mk_fake_ident_interner();
-        let ident = mock_interner.intern(@~"principal_skinner");
+        let ident = mock_interner.intern("principal_skinner");
 
         let var = codemap::respan(codemap::dummy_sp(), ast::variant_ {
             name: ident,
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 23084c34209..cca2ec89fd4 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -17,6 +17,7 @@
 
 use core::cmp::Equiv;
 use core::hashmap::HashMap;
+use syntax::parse::token::StringRef;
 
 pub struct Interner<T> {
     priv map: @mut HashMap<T, uint>,
@@ -77,6 +78,61 @@ pub impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
     }
 }
 
+pub struct StrInterner {
+    priv map: @mut HashMap<@~str, uint>,
+    priv vect: @mut ~[@~str],
+}
+
+// when traits can extend traits, we should extend index<uint,T> to get []
+pub impl StrInterner {
+    fn new() -> StrInterner {
+        StrInterner {
+            map: @mut HashMap::new(),
+            vect: @mut ~[],
+        }
+    }
+
+    fn prefill(init: &[&str]) -> StrInterner {
+        let rv = StrInterner::new();
+        for init.each() |v| { rv.intern(*v); }
+        rv
+    }
+
+    fn intern(&self, val: &str) -> uint {
+        match self.map.find_equiv(&StringRef(val)) {
+            Some(&idx) => return idx,
+            None => (),
+        }
+
+        let new_idx = self.len();
+        self.map.insert(@val.to_owned(), new_idx);
+        self.vect.push(@val.to_owned());
+        new_idx
+    }
+
+    fn gensym(&self, val: &str) -> uint {
+        let new_idx = self.len();
+        // leave out of .map to avoid colliding
+        self.vect.push(@val.to_owned());
+        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.
+    fn get(&self, idx: uint) -> @~str { self.vect[idx] }
+
+    fn len(&self) -> uint { let vect = &*self.vect; vect.len() }
+
+    fn find_equiv<Q:Hash + IterBytes + Equiv<@~str>>(&self, val: &Q)
+                                              -> Option<uint> {
+        match self.map.find_equiv(val) {
+            Some(v) => Some(*v),
+            None => None,
+        }
+    }
+}
+
 /* Key for thread-local data for sneaking interner information to the
 * encoder/decoder. It sounds like a hack because it is one.
 * Bonus ultra-hack: functions as keys don't work across crates,