about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-08-25 15:12:54 -0700
committerBrian Anderson <banderson@mozilla.com>2011-08-27 15:54:44 -0700
commit652332f9d44d0c3eb36c220a88ef37f7f875206f (patch)
tree61e00059bd5e16cc90b4f103cad5dff72f11fffb /src/comp
parentfaef9490ae724bce4802405f826d65988b2b7b05 (diff)
downloadrust-652332f9d44d0c3eb36c220a88ef37f7f875206f.tar.gz
rust-652332f9d44d0c3eb36c220a88ef37f7f875206f.zip
Convert std::map::new_str_hash to istrs. Issue #855
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/lib/llvm.rs14
-rw-r--r--src/comp/metadata/creader.rs12
-rw-r--r--src/comp/middle/gc.rs2
-rw-r--r--src/comp/middle/resolve.rs28
-rw-r--r--src/comp/middle/trans.rs57
-rw-r--r--src/comp/middle/trans_alt.rs8
-rw-r--r--src/comp/middle/trans_common.rs6
-rw-r--r--src/comp/middle/typeck.rs2
-rw-r--r--src/comp/syntax/ast.rs2
-rw-r--r--src/comp/syntax/ast_util.rs5
-rw-r--r--src/comp/syntax/ext/base.rs15
-rw-r--r--src/comp/syntax/ext/expand.rs9
-rw-r--r--src/comp/syntax/ext/simplext.rs46
-rw-r--r--src/comp/syntax/parse/parser.rs87
14 files changed, 164 insertions, 129 deletions
diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs
index 591e2270cd2..6692bcea070 100644
--- a/src/comp/lib/llvm.rs
+++ b/src/comp/lib/llvm.rs
@@ -901,22 +901,26 @@ native "cdecl" mod llvm = "rustllvm" {
 /* Memory-managed object interface to type handles. */
 
 obj type_names(type_names: std::map::hashmap<TypeRef, str>,
-               named_types: std::map::hashmap<str, TypeRef>) {
+               named_types: std::map::hashmap<istr, TypeRef>) {
 
     fn associate(s: str, t: TypeRef) {
-        assert (!named_types.contains_key(s));
+        assert (!named_types.contains_key(istr::from_estr(s)));
         assert (!type_names.contains_key(t));
         type_names.insert(t, s);
-        named_types.insert(s, t);
+        named_types.insert(istr::from_estr(s), t);
     }
 
     fn type_has_name(t: TypeRef) -> bool { ret type_names.contains_key(t); }
 
     fn get_name(t: TypeRef) -> str { ret type_names.get(t); }
 
-    fn name_has_type(s: str) -> bool { ret named_types.contains_key(s); }
+    fn name_has_type(s: str) -> bool {
+        ret named_types.contains_key(istr::from_estr(s));
+    }
 
-    fn get_type(s: str) -> TypeRef { ret named_types.get(s); }
+    fn get_type(s: str) -> TypeRef {
+        ret named_types.get(istr::from_estr(s));
+    }
 }
 
 fn mk_type_names() -> type_names {
diff --git a/src/comp/metadata/creader.rs b/src/comp/metadata/creader.rs
index e06f0ca455f..3f6d63cf577 100644
--- a/src/comp/metadata/creader.rs
+++ b/src/comp/metadata/creader.rs
@@ -47,7 +47,7 @@ fn read_crates(sess: session::session, crate: &ast::crate) {
 
 type env =
     @{sess: session::session,
-      crate_cache: @hashmap<str, int>,
+      crate_cache: @hashmap<istr, int>,
       library_search_paths: [str],
       mutable next_crate_num: ast::crate_num};
 
@@ -226,7 +226,7 @@ fn load_library_crate(sess: &session::session, span: span, ident: &ast::ident,
 
 fn resolve_crate(e: env, ident: ast::ident, metas: [@ast::meta_item],
                  span: span) -> ast::crate_num {
-    if !e.crate_cache.contains_key(ident) {
+    if !e.crate_cache.contains_key(istr::from_estr(ident)) {
         let cinfo =
             load_library_crate(e.sess, span, ident, metas,
                                e.library_search_paths);
@@ -236,7 +236,7 @@ fn resolve_crate(e: env, ident: ast::ident, metas: [@ast::meta_item],
 
         // Claim this crate number and cache it
         let cnum = e.next_crate_num;
-        e.crate_cache.insert(ident, cnum);
+        e.crate_cache.insert(istr::from_estr(ident), cnum);
         e.next_crate_num += 1;
 
         // Now resolve the crates referenced by this crate
@@ -248,7 +248,7 @@ fn resolve_crate(e: env, ident: ast::ident, metas: [@ast::meta_item],
         cstore::set_crate_data(cstore, cnum, cmeta);
         cstore::add_used_crate_file(cstore, cfilename);
         ret cnum;
-    } else { ret e.crate_cache.get(ident); }
+    } else { ret e.crate_cache.get(istr::from_estr(ident)); }
 }
 
 // Go through the crate metadata and load any crates that it references
@@ -261,10 +261,10 @@ fn resolve_crate_deps(e: env, cdata: &@[u8]) -> cstore::cnum_map {
         let extrn_cnum = dep.cnum;
         let cname = dep.ident;
         log #fmt["resolving dep %s", cname];
-        if e.crate_cache.contains_key(cname) {
+        if e.crate_cache.contains_key(istr::from_estr(cname)) {
             log "already have it";
             // We've already seen this crate
-            let local_cnum = e.crate_cache.get(cname);
+            let local_cnum = e.crate_cache.get(istr::from_estr(cname));
             cnum_map.insert(extrn_cnum, local_cnum);
         } else {
             log "need to load it";
diff --git a/src/comp/middle/gc.rs b/src/comp/middle/gc.rs
index 7ec131053fe..5b9ab91cebb 100644
--- a/src/comp/middle/gc.rs
+++ b/src/comp/middle/gc.rs
@@ -47,7 +47,7 @@ fn add_gc_root(cx: &@block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
     bcx = td_r.result.bcx;
     let lltydesc = td_r.result.val;
 
-    let gcroot = bcx_ccx(bcx).intrinsics.get("llvm.gcroot");
+    let gcroot = bcx_ccx(bcx).intrinsics.get(~"llvm.gcroot");
     let llvalptr = bld::PointerCast(bcx, llval, T_ptr(T_ptr(T_i8())));
 
     alt td_r.kind {
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index d3712f90da2..9c0c5281ccc 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -33,6 +33,7 @@ import std::option::is_none;
 import std::option::some;
 import std::option::none;
 import std::str;
+import std::istr;
 import syntax::print::pprust::*;
 
 export resolve_crate;
@@ -101,7 +102,7 @@ tag mod_index_entry {
     mie_tag_variant(/* tag item */@ast::item, /* variant index */uint);
 }
 
-type mod_index = hashmap<ident, list<mod_index_entry>>;
+type mod_index = hashmap<identistr, list<mod_index_entry>>;
 
 // A tuple of an imported def and the import stmt that brung it
 type glob_imp_def = {def: def, item: @ast::view_item};
@@ -110,7 +111,7 @@ type indexed_mod =
     {m: option::t<ast::_mod>,
      index: mod_index,
      mutable glob_imports: [glob_imp_def],
-     glob_imported_names: hashmap<str, import_state>};
+     glob_imported_names: hashmap<istr, import_state>};
 
 
 /* native modules can't contain tags, and we don't store their ASTs because we
@@ -954,7 +955,7 @@ fn lookup_in_local_mod(e: &env, node_id: node_id, sp: &span, id: &ident,
         ret none::<def>; // name is not visible
 
     }
-    alt info.index.find(id) {
+    alt info.index.find(istr::from_estr(id)) {
       none. { }
       some(lst_) {
         let lst = lst_;
@@ -1009,14 +1010,15 @@ fn lookup_glob_in_mod(e: &env, info: @indexed_mod, sp: &span, id: &ident,
     // since we don't know what names we have in advance,
     // absence takes the place of todo()
 
-    if !info.glob_imported_names.contains_key(id) {
-        info.glob_imported_names.insert(id, resolving(sp));
+    if !info.glob_imported_names.contains_key(istr::from_estr(id)) {
+        info.glob_imported_names.insert(istr::from_estr(id), resolving(sp));
         let val = per_ns(e, info, sp, id, ns_value, dr);
         let typ = per_ns(e, info, sp, id, ns_type, dr);
         let md = per_ns(e, info, sp, id, ns_module, dr);
-        info.glob_imported_names.insert(id, resolved(val, typ, md));
+        info.glob_imported_names.insert(istr::from_estr(id),
+                                        resolved(val, typ, md));
     }
-    alt info.glob_imported_names.get(id) {
+    alt info.glob_imported_names.get(istr::from_estr(id)) {
       todo(_, _, _, _, _) { e.sess.bug("Shouldn't've put a todo in."); }
       resolving(sp) {
         ret none::<def>; //circularity is okay in import globs
@@ -1071,10 +1073,12 @@ fn lookup_in_mie(e: &env, mie: &mod_index_entry, ns: namespace) ->
 
 
 // Module indexing
-fn add_to_index(index: &hashmap<ident, list<mod_index_entry>>, id: &ident,
-                ent: &mod_index_entry) {
+fn add_to_index(index: &hashmap<identistr, list<mod_index_entry>>,
+                id: &ident, ent: &mod_index_entry) {
+    let id = istr::from_estr(id);
     alt index.find(id) {
-      none. { index.insert(id, cons(ent, @nil::<mod_index_entry>)); }
+      none. { index.insert(id,
+                           cons(ent, @nil::<mod_index_entry>)); }
       some(prev) { index.insert(id, cons(ent, @prev)); }
     }
 }
@@ -1187,9 +1191,9 @@ fn check_for_collisions(e: &@env, c: &ast::crate) {
     // Module indices make checking those relatively simple -- just check each
     // name for multiple entities in the same namespace.
     for each m: @{key: ast::node_id, val: @indexed_mod} in e.mod_map.items() {
-        for each name: @{key: ident, val: list<mod_index_entry>} in
+        for each name: @{key: identistr, val: list<mod_index_entry>} in
                  m.val.index.items() {
-            check_mod_name(*e, name.key, name.val);
+            check_mod_name(*e, istr::to_estr(name.key), name.val);
         }
     }
     // Other scopes have to be checked the hard way.
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 649d3a7eb53..0fd6762a4d1 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -355,23 +355,27 @@ fn decl_glue(llmod: ModuleRef, cx: &crate_ctxt, s: &str) -> ValueRef {
     ret decl_cdecl_fn(llmod, s, T_fn([T_taskptr(cx)], T_void()));
 }
 
-fn get_extern_fn(externs: &hashmap<str, ValueRef>, llmod: ModuleRef,
+fn get_extern_fn(externs: &hashmap<istr, ValueRef>, llmod: ModuleRef,
                  name: &str, cc: uint, ty: TypeRef) -> ValueRef {
-    if externs.contains_key(name) { ret externs.get(name); }
+    if externs.contains_key(istr::from_estr(name)) {
+        ret externs.get(istr::from_estr(name));
+    }
     let f = decl_fn(llmod, name, cc, ty);
-    externs.insert(name, f);
+    externs.insert(istr::from_estr(name), f);
     ret f;
 }
 
-fn get_extern_const(externs: &hashmap<str, ValueRef>, llmod: ModuleRef,
+fn get_extern_const(externs: &hashmap<istr, ValueRef>, llmod: ModuleRef,
                     name: &str, ty: TypeRef) -> ValueRef {
-    if externs.contains_key(name) { ret externs.get(name); }
+    if externs.contains_key(istr::from_estr(name)) {
+        ret externs.get(istr::from_estr(name));
+    }
     let c = llvm::LLVMAddGlobal(llmod, ty, str::buf(name));
-    externs.insert(name, c);
+    externs.insert(istr::from_estr(name), c);
     ret c;
 }
 
-fn get_simple_extern_fn(externs: &hashmap<str, ValueRef>, llmod: ModuleRef,
+fn get_simple_extern_fn(externs: &hashmap<istr, ValueRef>, llmod: ModuleRef,
                         name: &str, n_args: int) -> ValueRef {
     let inputs = std::vec::init_elt::<TypeRef>(T_int(), n_args as uint);
     let output = T_int();
@@ -379,7 +383,7 @@ fn get_simple_extern_fn(externs: &hashmap<str, ValueRef>, llmod: ModuleRef,
     ret get_extern_fn(externs, llmod, name, lib::llvm::LLVMCCallConv, t);
 }
 
-fn trans_native_call(cx: &@block_ctxt, externs: &hashmap<str, ValueRef>,
+fn trans_native_call(cx: &@block_ctxt, externs: &hashmap<istr, ValueRef>,
                      llmod: ModuleRef, name: &str, args: &[ValueRef]) ->
    ValueRef {
     let n: int = std::vec::len::<ValueRef>(args) as int;
@@ -2287,8 +2291,8 @@ fn call_memmove(cx: &@block_ctxt, dst: ValueRef, src: ValueRef,
     // LLVM complains -- not even a constant element of a tydesc works).
 
     let i = bcx_ccx(cx).intrinsics;
-    assert (i.contains_key("llvm.memmove.p0i8.p0i8.i32"));
-    let memmove = i.get("llvm.memmove.p0i8.p0i8.i32");
+    assert (i.contains_key(~"llvm.memmove.p0i8.p0i8.i32"));
+    let memmove = i.get(~"llvm.memmove.p0i8.p0i8.i32");
     let src_ptr = bld::PointerCast(cx, src, T_ptr(T_i8()));
     let dst_ptr = bld::PointerCast(cx, dst, T_ptr(T_i8()));
     let size = bld::IntCast(cx, n_bytes, T_i32());
@@ -2304,8 +2308,8 @@ fn call_bzero(cx: &@block_ctxt, dst: ValueRef, n_bytes: ValueRef,
     // FIXME: switch to the 64-bit variant when on such a platform.
 
     let i = bcx_ccx(cx).intrinsics;
-    assert (i.contains_key("llvm.memset.p0i8.i32"));
-    let memset = i.get("llvm.memset.p0i8.i32");
+    assert (i.contains_key(~"llvm.memset.p0i8.i32"));
+    let memset = i.get(~"llvm.memset.p0i8.i32");
     let dst_ptr = bld::PointerCast(cx, dst, T_ptr(T_i8()));
     let size = bld::IntCast(cx, n_bytes, T_i32());
     let align =
@@ -4524,8 +4528,8 @@ fn trans_log(lvl: int, cx: &@block_ctxt, e: &@ast::expr) -> result {
     let lcx = cx.fcx.lcx;
     let modname = str::connect(lcx.module_path, "::");
     let global;
-    if lcx.ccx.module_data.contains_key(modname) {
-        global = lcx.ccx.module_data.get(modname);
+    if lcx.ccx.module_data.contains_key(istr::from_estr(modname)) {
+        global = lcx.ccx.module_data.get(istr::from_estr(modname));
     } else {
         let s =
             link::mangle_internal_name_by_path_and_seq(lcx.ccx,
@@ -4536,7 +4540,7 @@ fn trans_log(lvl: int, cx: &@block_ctxt, e: &@ast::expr) -> result {
         llvm::LLVMSetInitializer(global, C_null(T_int()));
         llvm::LLVMSetLinkage(global,
                              lib::llvm::LLVMInternalLinkage as llvm::Linkage);
-        lcx.ccx.module_data.insert(modname, global);
+        lcx.ccx.module_data.insert(istr::from_estr(modname), global);
     }
     let log_cx = new_scope_block_ctxt(cx, "log");
     let after_cx = new_sub_block_ctxt(cx, "after");
@@ -6168,7 +6172,7 @@ fn vi2p(cx: &@block_ctxt, v: ValueRef, t: TypeRef) -> ValueRef {
 
 fn p2i(v: ValueRef) -> ValueRef { ret llvm::LLVMConstPtrToInt(v, T_int()); }
 
-fn declare_intrinsics(llmod: ModuleRef) -> hashmap<str, ValueRef> {
+fn declare_intrinsics(llmod: ModuleRef) -> hashmap<istr, ValueRef> {
     let T_memmove32_args: [TypeRef] =
         [T_ptr(T_i8()), T_ptr(T_i8()), T_i32(), T_i32(), T_i1()];
     let T_memmove64_args: [TypeRef] =
@@ -6198,19 +6202,19 @@ fn declare_intrinsics(llmod: ModuleRef) -> hashmap<str, ValueRef> {
                       T_fn(T_memset64_args, T_void()));
     let trap = decl_cdecl_fn(llmod, "llvm.trap", T_fn(T_trap_args, T_void()));
     let intrinsics = new_str_hash::<ValueRef>();
-    intrinsics.insert("llvm.gcroot", gcroot);
-    intrinsics.insert("llvm.gcread", gcread);
-    intrinsics.insert("llvm.memmove.p0i8.p0i8.i32", memmove32);
-    intrinsics.insert("llvm.memmove.p0i8.p0i8.i64", memmove64);
-    intrinsics.insert("llvm.memset.p0i8.i32", memset32);
-    intrinsics.insert("llvm.memset.p0i8.i64", memset64);
-    intrinsics.insert("llvm.trap", trap);
+    intrinsics.insert(~"llvm.gcroot", gcroot);
+    intrinsics.insert(~"llvm.gcread", gcread);
+    intrinsics.insert(~"llvm.memmove.p0i8.p0i8.i32", memmove32);
+    intrinsics.insert(~"llvm.memmove.p0i8.p0i8.i64", memmove64);
+    intrinsics.insert(~"llvm.memset.p0i8.i32", memset32);
+    intrinsics.insert(~"llvm.memset.p0i8.i64", memset64);
+    intrinsics.insert(~"llvm.trap", trap);
     ret intrinsics;
 }
 
 fn trap(bcx: &@block_ctxt) {
     let v: [ValueRef] = [];
-    alt bcx_ccx(bcx).intrinsics.find("llvm.trap") {
+    alt bcx_ccx(bcx).intrinsics.find(~"llvm.trap") {
       some(x) { bld::Call(bcx, x, v); }
       _ { bcx_ccx(bcx).sess.bug("unbound llvm.trap in trap"); }
     }
@@ -6264,8 +6268,9 @@ fn create_module_map(ccx: &@crate_ctxt) -> ValueRef {
     llvm::LLVMSetLinkage(map,
                          lib::llvm::LLVMInternalLinkage as llvm::Linkage);
     let elts: [ValueRef] = [];
-    for each item: @{key: str, val: ValueRef} in ccx.module_data.items() {
-        let elt = C_struct([p2i(C_cstr(ccx, item.key)), p2i(item.val)]);
+    for each item: @{key: istr, val: ValueRef} in ccx.module_data.items() {
+        let elt = C_struct([p2i(C_cstr(ccx, istr::to_estr(item.key))),
+                            p2i(item.val)]);
         elts += [elt];
     }
     let term = C_struct([C_int(0), C_int(0)]);
diff --git a/src/comp/middle/trans_alt.rs b/src/comp/middle/trans_alt.rs
index 5f99f921312..57539c2a3c5 100644
--- a/src/comp/middle/trans_alt.rs
+++ b/src/comp/middle/trans_alt.rs
@@ -1,4 +1,5 @@
 import std::str;
+import std::istr;
 import std::vec;
 import std::option;
 import option::some;
@@ -303,7 +304,8 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
             // the actual arm block.
             for each @{key, val} in data.id_map.items() {
                 bcx.fcx.lllocals.insert
-                    (val, option::get(assoc(key, m[0].bound)));
+                    (val, option::get(assoc(istr::to_estr(key),
+                                            m[0].bound)));
             }
             let {bcx: guard_bcx, val: guard_val} =
                 trans::trans_expr(guard_cx, e);
@@ -467,12 +469,12 @@ fn make_phi_bindings(bcx: &@block_ctxt, map: &[exit_node],
                      ids: &ast_util::pat_id_map) -> bool {
     let our_block = bcx.llbb as uint;
     let success = true;
-    for each item: @{key: ast::ident, val: ast::node_id} in ids.items() {
+    for each item: @{key: ast::identistr, val: ast::node_id} in ids.items() {
         let llbbs = [];
         let vals = [];
         for ex: exit_node in map {
             if ex.to as uint == our_block {
-                alt assoc(item.key, ex.bound) {
+                alt assoc(istr::to_estr(item.key), ex.bound) {
                   some(val) { llbbs += [ex.from]; vals += [val]; }
                   none. { }
                 }
diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs
index 614f371b9bb..77a101d9f68 100644
--- a/src/comp/middle/trans_common.rs
+++ b/src/comp/middle/trans_common.rs
@@ -127,8 +127,8 @@ type crate_ctxt =
      llmod: ModuleRef,
      td: target_data,
      tn: type_names,
-     externs: hashmap<str, ValueRef>,
-     intrinsics: hashmap<str, ValueRef>,
+     externs: hashmap<istr, ValueRef>,
+     intrinsics: hashmap<istr, ValueRef>,
      item_ids: hashmap<ast::node_id, ValueRef>,
      ast_map: ast_map::map,
      item_symbols: hashmap<ast::node_id, str>,
@@ -141,7 +141,7 @@ type crate_ctxt =
      consts: hashmap<ast::node_id, ValueRef>,
      obj_methods: hashmap<ast::node_id, ()>,
      tydescs: hashmap<ty::t, @tydesc_info>,
-     module_data: hashmap<str, ValueRef>,
+     module_data: hashmap<istr, ValueRef>,
      lltypes: hashmap<ty::t, TypeRef>,
      glues: @glue_fns,
      names: namegen,
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 1985928442b..5a71c99cec2 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -1322,7 +1322,7 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast_util::pat_id_map, pat: &@ast::pat,
         let vid = lookup_local(fcx, pat.span, pat.id);
         let typ = ty::mk_var(fcx.ccx.tcx, vid);
         typ = demand::simple(fcx, pat.span, expected, typ);
-        let canon_id = map.get(name);
+        let canon_id = map.get(istr::from_estr(name));
         if canon_id != pat.id {
             let ct =
                 ty::mk_var(fcx.ccx.tcx,
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index d44baebb6f3..d380fbecdb4 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -8,6 +8,8 @@ import codemap::filename;
 type spanned<T> = {node: T, span: span};
 
 type ident = str;
+type identistr = istr;
+
 // Functions may or may not have names.
 type fn_ident = option::t<ident>;
 
diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs
index 15f41af5cac..687070da24f 100644
--- a/src/comp/syntax/ast_util.rs
+++ b/src/comp/syntax/ast_util.rs
@@ -1,4 +1,5 @@
 import std::str;
+import std::istr;
 import std::option;
 import codemap::span;
 import ast::*;
@@ -43,7 +44,7 @@ fn def_id_of_def(d: def) -> def_id {
     }
 }
 
-type pat_id_map = std::map::hashmap<str, ast::node_id>;
+type pat_id_map = std::map::hashmap<istr, ast::node_id>;
 
 // This is used because same-named variables in alternative patterns need to
 // use the node_id of their namesake in the first pattern.
@@ -51,7 +52,7 @@ fn pat_id_map(pat: &@pat) -> pat_id_map {
     let map = std::map::new_str_hash::<node_id>();
     for each bound in pat_bindings(pat) {
         let name = alt bound.node { pat_bind(n) { n } };
-        map.insert(name, bound.id);
+        map.insert(istr::from_estr(name), bound.id);
     }
     ret map;
 }
diff --git a/src/comp/syntax/ext/base.rs b/src/comp/syntax/ext/base.rs
index 6d1bd6626c2..a354aa67090 100644
--- a/src/comp/syntax/ext/base.rs
+++ b/src/comp/syntax/ext/base.rs
@@ -1,3 +1,4 @@
+import std::istr;
 import std::vec;
 import std::option;
 import std::map::hashmap;
@@ -19,17 +20,17 @@ tag syntax_extension {
 
 // A temporary hard-coded map of methods for expanding syntax extension
 // AST nodes into full ASTs
-fn syntax_expander_table() -> hashmap<str, syntax_extension> {
+fn syntax_expander_table() -> hashmap<istr, syntax_extension> {
     let syntax_expanders = new_str_hash::<syntax_extension>();
-    syntax_expanders.insert("fmt", normal(ext::fmt::expand_syntax_ext));
-    syntax_expanders.insert("env", normal(ext::env::expand_syntax_ext));
-    syntax_expanders.insert("macro",
+    syntax_expanders.insert(~"fmt", normal(ext::fmt::expand_syntax_ext));
+    syntax_expanders.insert(~"env", normal(ext::env::expand_syntax_ext));
+    syntax_expanders.insert(~"macro",
                             macro_defining(ext::simplext::add_new_extension));
-    syntax_expanders.insert("concat_idents",
+    syntax_expanders.insert(~"concat_idents",
                             normal(ext::concat_idents::expand_syntax_ext));
-    syntax_expanders.insert("ident_to_str",
+    syntax_expanders.insert(~"ident_to_str",
                             normal(ext::ident_to_str::expand_syntax_ext));
-    syntax_expanders.insert("log_syntax",
+    syntax_expanders.insert(~"log_syntax",
                             normal(ext::log_syntax::expand_syntax_ext));
     ret syntax_expanders;
 }
diff --git a/src/comp/syntax/ext/expand.rs b/src/comp/syntax/ext/expand.rs
index 149216aa6cd..542b2805402 100644
--- a/src/comp/syntax/ext/expand.rs
+++ b/src/comp/syntax/ext/expand.rs
@@ -5,6 +5,7 @@ import std::option::some;
 
 import std::map::hashmap;
 import std::vec;
+import std::istr;
 
 import syntax::ast::crate;
 import syntax::ast::expr_;
@@ -14,7 +15,7 @@ import syntax::fold::*;
 import syntax::ext::base::*;
 
 
-fn expand_expr(exts: &hashmap<str, syntax_extension>, cx: &ext_ctxt,
+fn expand_expr(exts: &hashmap<istr, syntax_extension>, cx: &ext_ctxt,
                e: &expr_, fld: ast_fold, orig: &fn(&expr_, ast_fold) -> expr_)
    -> expr_ {
     ret alt e {
@@ -23,7 +24,7 @@ fn expand_expr(exts: &hashmap<str, syntax_extension>, cx: &ext_ctxt,
               mac_invoc(pth, args, body) {
                 assert (vec::len(pth.node.idents) > 0u);
                 let extname = pth.node.idents[0];
-                alt exts.find(extname) {
+                alt exts.find(istr::from_estr(extname)) {
                   none. {
                     cx.span_fatal(pth.span,
                                   #fmt["macro undefined: '%s'", extname])
@@ -40,7 +41,9 @@ 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(
+                        istr::from_estr(named_extension.ident),
+                        named_extension.ext);
                     ast::expr_rec([], none)
                   }
                 }
diff --git a/src/comp/syntax/ext/simplext.rs b/src/comp/syntax/ext/simplext.rs
index fb4402732ae..b0d7cd26020 100644
--- a/src/comp/syntax/ext/simplext.rs
+++ b/src/comp/syntax/ext/simplext.rs
@@ -2,6 +2,7 @@ use std;
 
 import codemap::span;
 import std::vec;
+import std::istr;
 import std::option;
 import std::map::hashmap;
 import std::map::new_str_hash;
@@ -18,6 +19,7 @@ import fold::*;
 import ast::node_id;
 import ast_util::respan;
 import ast::ident;
+import ast::identistr;
 import ast::path;
 import ast::ty;
 import ast::blk;
@@ -155,9 +157,9 @@ fn compose_sels(s1: selector, s2: selector) -> selector {
 
 
 type binders =
-    {real_binders: hashmap<ident, selector>,
+    {real_binders: hashmap<identistr, selector>,
      mutable literal_ast_matchers: [selector]};
-type bindings = hashmap<ident, arb_depth<matchable>>;
+type bindings = hashmap<identistr, arb_depth<matchable>>;
 
 fn acumm_bindings(_cx: &ext_ctxt, _b_dest: &bindings, _b_src: &bindings) { }
 
@@ -189,7 +191,8 @@ fn use_selectors_to_bind(b: &binders, e: @expr) -> option::t<bindings> {
         alt sel(match_expr(e)) { none. { ret none; } _ { } }
     }
     let never_mind: bool = false;
-    for each pair: @{key: ident, val: selector} in b.real_binders.items() {
+    for each pair: @{key: identistr,
+                     val: selector} in b.real_binders.items() {
         alt pair.val(match_expr(e)) {
           none. { never_mind = true; }
           some(mtc) { res.insert(pair.key, mtc); }
@@ -262,10 +265,12 @@ fn follow_for_trans(cx: &ext_ctxt, mmaybe: &option::t<arb_depth<matchable>>,
 
 /* helper for transcribe_exprs: what vars from `b` occur in `e`? */
 iter free_vars(b: &bindings, e: @expr) -> ident {
-    let idents: hashmap<ident, ()> = new_str_hash::<()>();
+    let idents: hashmap<identistr, ()> = new_str_hash::<()>();
     fn mark_ident(i: &ident, _fld: ast_fold, b: &bindings,
-                  idents: &hashmap<ident, ()>) -> ident {
-        if b.contains_key(i) { idents.insert(i, ()); }
+                  idents: &hashmap<identistr, ()>) -> ident {
+        if b.contains_key(istr::from_estr(i)) {
+            idents.insert(istr::from_estr(i), ());
+        }
         ret i;
     }
     // using fold is a hack: we want visit, but it doesn't hit idents ) :
@@ -276,7 +281,7 @@ iter free_vars(b: &bindings, e: @expr) -> ident {
     let f = make_fold(f_pre);
     f.fold_expr(e); // ignore result
     dummy_out(f);
-    for each id: ident in idents.keys() { put id; }
+    for each id: identistr in idents.keys() { put istr::to_estr(id); }
 }
 
 
@@ -293,7 +298,7 @@ fn transcribe_exprs(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
             /* we need to walk over all the free vars in lockstep, except for
             the leaves, which are just duplicated */
             for each fv: ident in free_vars(b, repeat_me) {
-                let cur_pos = follow(b.get(fv), idx_path);
+                let cur_pos = follow(b.get(istr::from_estr(fv)), idx_path);
                 alt cur_pos {
                   leaf(_) { }
                   seq(ms, _) {
@@ -345,7 +350,7 @@ fn transcribe_exprs(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
 // substitute, in a position that's required to be an ident
 fn transcribe_ident(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
                     i: &ident, _fld: ast_fold) -> ident {
-    ret alt follow_for_trans(cx, b.find(i), idx_path) {
+    ret alt follow_for_trans(cx, b.find(istr::from_estr(i)), idx_path) {
           some(match_ident(a_id)) { a_id.node }
           some(m) { match_error(cx, m, "an identifier") }
           none. { i }
@@ -357,7 +362,8 @@ fn transcribe_path(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
                    p: &path_, _fld: ast_fold) -> path_ {
     // Don't substitute into qualified names.
     if vec::len(p.types) > 0u || vec::len(p.idents) != 1u { ret p; }
-    ret alt follow_for_trans(cx, b.find(p.idents[0]), idx_path) {
+    ret alt follow_for_trans(cx, b.find(
+        istr::from_estr(p.idents[0])), idx_path) {
           some(match_ident(id)) {
             {global: false, idents: [id.node], types: []}
           }
@@ -378,7 +384,8 @@ fn transcribe_expr(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
             if vec::len(p.node.types) > 0u || vec::len(p.node.idents) != 1u {
                 e
             }
-            alt follow_for_trans(cx, b.find(p.node.idents[0]), idx_path) {
+            alt follow_for_trans(cx, b.find(
+                istr::from_estr(p.node.idents[0])), idx_path) {
               some(match_ident(id)) {
                 expr_path(respan(id.span,
                                  {global: false,
@@ -402,7 +409,8 @@ fn transcribe_type(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
           ast::ty_path(pth, _) {
             alt path_to_ident(pth) {
               some(id) {
-                alt follow_for_trans(cx, b.find(id), idx_path) {
+                alt follow_for_trans(cx, b.find(
+                    istr::from_estr(id)), idx_path) {
                   some(match_ty(ty)) { ty.node }
                   some(m) { match_error(cx, m, "a type") }
                   none. { orig(t, fld) }
@@ -424,7 +432,8 @@ fn transcribe_block(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
                     orig: fn(&blk_, ast_fold) -> blk_) -> blk_ {
     ret alt block_to_ident(blk) {
           some(id) {
-            alt follow_for_trans(cx, b.find(id), idx_path) {
+            alt follow_for_trans(cx, b.find(
+                istr::from_estr(id)), idx_path) {
               some(match_block(new_blk)) { new_blk.node }
 
 
@@ -525,10 +534,11 @@ fn p_t_s_r_path(cx: &ext_ctxt, p: &path, s: &selector, b: &binders) {
                   _ { cx.bug("broken traversal in p_t_s_r") }
                 }
         }
-        if b.real_binders.contains_key(p_id) {
+        if b.real_binders.contains_key(istr::from_estr(p_id)) {
             cx.span_fatal(p.span, "duplicate binding identifier");
         }
-        b.real_binders.insert(p_id, compose_sels(s, bind select(cx, _)));
+        b.real_binders.insert(istr::from_estr(p_id),
+                              compose_sels(s, bind select(cx, _)));
       }
       none. { }
     }
@@ -573,7 +583,8 @@ fn p_t_s_r_mac(cx: &ext_ctxt, mac: &ast::mac, s: &selector, b: &binders) {
                         }
                 }
                 let final_step = bind select_pt_1(cx, _, select_pt_2);
-                b.real_binders.insert(id, compose_sels(s, final_step));
+                b.real_binders.insert(
+                    istr::from_estr(id), compose_sels(s, final_step));
               }
               none. { no_des(cx, pth.span, "under `#<>`"); }
             }
@@ -593,7 +604,8 @@ fn p_t_s_r_mac(cx: &ext_ctxt, mac: &ast::mac, s: &selector, b: &binders) {
                     }
             }
             let final_step = bind select_pt_1(cx, _, select_pt_2);
-            b.real_binders.insert(id, compose_sels(s, final_step));
+            b.real_binders.insert(istr::from_estr(id),
+                                  compose_sels(s, final_step));
           }
           none. { no_des(cx, blk.span, "under `#{}`"); }
         }
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index b5d71a6ee9c..c0beb8a32c3 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -53,7 +53,7 @@ type parser =
         fn get_str(token::str_num) -> str;
         fn get_reader() -> lexer::reader;
         fn get_filemap() -> codemap::filemap;
-        fn get_bad_expr_words() -> hashmap<str, ()>;
+        fn get_bad_expr_words() -> hashmap<istr, ()>;
         fn get_chpos() -> uint;
         fn get_byte_pos() -> uint;
         fn get_id() -> node_id;
@@ -84,7 +84,7 @@ fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader,
                      mutable restr: restriction,
                      rdr: lexer::reader,
                      precs: @[op_spec],
-                     bad_words: hashmap<str, ()>) {
+                     bad_words: hashmap<istr, ()>) {
         fn peek() -> token::token { ret tok; }
         fn bump() {
             last_tok_span = tok_span;
@@ -132,7 +132,7 @@ fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader,
         }
         fn get_reader() -> lexer::reader { ret rdr; }
         fn get_filemap() -> codemap::filemap { ret rdr.get_filemap(); }
-        fn get_bad_expr_words() -> hashmap<str, ()> { ret bad_words; }
+        fn get_bad_expr_words() -> hashmap<istr, ()> { ret bad_words; }
         fn get_chpos() -> uint { ret rdr.get_chpos(); }
         fn get_byte_pos() -> uint { ret rdr.get_byte_pos(); }
         fn get_id() -> node_id { ret next_node_id(sess); }
@@ -148,44 +148,44 @@ fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader,
 // These are the words that shouldn't be allowed as value identifiers,
 // because, if used at the start of a line, they will cause the line to be
 // interpreted as a specific kind of statement, which would be confusing.
-fn bad_expr_word_table() -> hashmap<str, ()> {
+fn bad_expr_word_table() -> hashmap<istr, ()> {
     let words = new_str_hash();
-    words.insert("mod", ());
-    words.insert("if", ());
-    words.insert("else", ());
-    words.insert("while", ());
-    words.insert("do", ());
-    words.insert("alt", ());
-    words.insert("for", ());
-    words.insert("each", ());
-    words.insert("break", ());
-    words.insert("cont", ());
-    words.insert("put", ());
-    words.insert("ret", ());
-    words.insert("be", ());
-    words.insert("fail", ());
-    words.insert("type", ());
-    words.insert("resource", ());
-    words.insert("check", ());
-    words.insert("assert", ());
-    words.insert("claim", ());
-    words.insert("prove", ());
-    words.insert("native", ());
-    words.insert("fn", ());
-    words.insert("block", ());
-    words.insert("lambda", ());
-    words.insert("pure", ());
-    words.insert("iter", ());
-    words.insert("block", ());
-    words.insert("import", ());
-    words.insert("export", ());
-    words.insert("let", ());
-    words.insert("const", ());
-    words.insert("log", ());
-    words.insert("log_err", ());
-    words.insert("tag", ());
-    words.insert("obj", ());
-    words.insert("copy", ());
+    words.insert(~"mod", ());
+    words.insert(~"if", ());
+    words.insert(~"else", ());
+    words.insert(~"while", ());
+    words.insert(~"do", ());
+    words.insert(~"alt", ());
+    words.insert(~"for", ());
+    words.insert(~"each", ());
+    words.insert(~"break", ());
+    words.insert(~"cont", ());
+    words.insert(~"put", ());
+    words.insert(~"ret", ());
+    words.insert(~"be", ());
+    words.insert(~"fail", ());
+    words.insert(~"type", ());
+    words.insert(~"resource", ());
+    words.insert(~"check", ());
+    words.insert(~"assert", ());
+    words.insert(~"claim", ());
+    words.insert(~"prove", ());
+    words.insert(~"native", ());
+    words.insert(~"fn", ());
+    words.insert(~"block", ());
+    words.insert(~"lambda", ());
+    words.insert(~"pure", ());
+    words.insert(~"iter", ());
+    words.insert(~"block", ());
+    words.insert(~"import", ());
+    words.insert(~"export", ());
+    words.insert(~"let", ());
+    words.insert(~"const", ());
+    words.insert(~"log", ());
+    words.insert(~"log_err", ());
+    words.insert(~"tag", ());
+    words.insert(~"obj", ());
+    words.insert(~"copy", ());
     ret words;
 }
 
@@ -273,7 +273,7 @@ fn check_bad_word(p: &parser) {
     alt p.peek() {
       token::IDENT(sid, false) {
         let w = p.get_str(sid);
-        if p.get_bad_expr_words().contains_key(w) {
+        if p.get_bad_expr_words().contains_key(istr::from_estr(w)) {
             p.fatal("found " + w + " in expression position");
         }
       }
@@ -1455,7 +1455,8 @@ fn parse_pat(p: &parser) -> @ast::pat {
                 p.bump();
                 subpat = parse_pat(p);
             } else {
-                if p.get_bad_expr_words().contains_key(fieldname) {
+                if p.get_bad_expr_words()
+                    .contains_key(istr::from_estr(fieldname)) {
                     p.fatal("found " + fieldname + " in binding position");
                 }
                 subpat =
@@ -2061,7 +2062,7 @@ fn parse_item_tag(p: &parser, attrs: &[ast::attribute]) -> @ast::item {
     let variants: [ast::variant] = [];
     // Newtype syntax
     if p.peek() == token::EQ {
-        if p.get_bad_expr_words().contains_key(id) {
+        if p.get_bad_expr_words().contains_key(istr::from_estr(id)) {
             p.fatal("found " + id + " in tag constructor position");
         }
         p.bump();