about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-05-05 12:17:59 -0400
committerNiko Matsakis <niko@alum.mit.edu>2013-05-05 12:17:59 -0400
commit0b0b8018a6a1271e6c8e82230e2e8496eebbba3f (patch)
treea4f6bdc672d069c3454c8e26462d4a4bb3ad9e7c /src
parent6806900a7c63950feb2540347fc3f94d83074bbd (diff)
downloadrust-0b0b8018a6a1271e6c8e82230e2e8496eebbba3f.tar.gz
rust-0b0b8018a6a1271e6c8e82230e2e8496eebbba3f.zip
add warning for #6248 and remove instances of it
Diffstat (limited to 'src')
-rw-r--r--src/libcore/hashmap.rs13
-rw-r--r--src/librustc/metadata/encoder.rs8
-rw-r--r--src/librustc/middle/borrowck/gather_loans/lifetime.rs36
-rw-r--r--src/librustc/middle/check_const.rs2
-rw-r--r--src/librustc/middle/check_match.rs4
-rw-r--r--src/librustc/middle/kind.rs8
-rw-r--r--src/librustc/middle/lint.rs2
-rw-r--r--src/librustc/middle/liveness.rs8
-rw-r--r--src/librustc/middle/mem_categorization.rs4
-rw-r--r--src/librustc/middle/moves.rs2
-rw-r--r--src/librustc/middle/privacy.rs4
-rw-r--r--src/librustc/middle/region.rs2
-rw-r--r--src/librustc/middle/trans/_match.rs6
-rw-r--r--src/librustc/middle/trans/base.rs6
-rw-r--r--src/librustc/middle/trans/closure.rs2
-rw-r--r--src/librustc/middle/trans/consts.rs6
-rw-r--r--src/librustc/middle/trans/controlflow.rs2
-rw-r--r--src/librustc/middle/trans/debuginfo.rs6
-rw-r--r--src/librustc/middle/trans/expr.rs4
-rw-r--r--src/librustc/middle/trans/foreign.rs2
-rw-r--r--src/librustc/middle/trans/machine.rs2
-rw-r--r--src/librustc/middle/trans/meth.rs8
-rw-r--r--src/librustc/middle/trans/monomorphize.rs14
-rw-r--r--src/librustc/middle/trans/reachable.rs19
-rw-r--r--src/librustc/middle/trans/reflect.rs7
-rw-r--r--src/librustc/middle/trans/type_use.rs33
-rw-r--r--src/librustc/middle/ty.rs4
-rw-r--r--src/librustc/middle/typeck/check/_match.rs2
-rw-r--r--src/librustc/middle/typeck/check/mod.rs8
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs2
-rw-r--r--src/librustc/middle/typeck/coherence.rs6
-rw-r--r--src/librustc/middle/typeck/collect.rs2
32 files changed, 142 insertions, 92 deletions
diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs
index ad1994a92d2..8ed54741f12 100644
--- a/src/libcore/hashmap.rs
+++ b/src/libcore/hashmap.rs
@@ -25,6 +25,7 @@ use rand;
 use uint;
 use vec;
 use util::unreachable;
+use kinds::Copy;
 
 static INITIAL_CAPACITY: uint = 32u; // 2^5
 
@@ -529,6 +530,18 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
     }
 }
 
+pub impl<K: Hash + Eq, V: Copy> HashMap<K, V> {
+    /// Like `find`, but returns a copy of the value.
+    fn find_copy(&self, k: &K) -> Option<V> {
+        self.find(k).map_consume(|v| copy *v)
+    }
+
+    /// Like `get`, but returns a copy of the value.
+    fn get_copy(&self, k: &K) -> V {
+        copy *self.get(k)
+    }
+}
+
 impl<K:Hash + Eq,V:Eq> Eq for HashMap<K, V> {
     fn eq(&self, other: &HashMap<K, V>) -> bool {
         if self.len() != other.len() { return false; }
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index dd4ef0d2e68..6d7442b1ed5 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -190,7 +190,7 @@ fn encode_type_param_bounds(ebml_w: &writer::Encoder,
                             ecx: @EncodeContext,
                             params: &OptVec<TyParam>) {
     let ty_param_defs =
-        @params.map_to_vec(|param| *ecx.tcx.ty_param_defs.get(&param.id));
+        @params.map_to_vec(|param| ecx.tcx.ty_param_defs.get_copy(&param.id));
     encode_ty_type_param_defs(ebml_w, ecx, ty_param_defs,
                               tag_items_data_item_ty_param_bounds);
 }
@@ -275,7 +275,7 @@ fn encode_symbol(ecx: @EncodeContext, ebml_w: &writer::Encoder, id: node_id) {
 fn encode_discriminant(ecx: @EncodeContext, ebml_w: &writer::Encoder,
                        id: node_id) {
     ebml_w.start_tag(tag_items_data_item_symbol);
-    ebml_w.writer.write(str::to_bytes(**ecx.discrim_symbols.get(&id)));
+    ebml_w.writer.write(str::to_bytes(*ecx.discrim_symbols.get_copy(&id)));
     ebml_w.end_tag();
 }
 
@@ -1035,7 +1035,7 @@ fn encode_info_for_items(ecx: @EncodeContext, ebml_w: &writer::Encoder,
             let ebml_w = copy *ebml_w;
             |i, cx, v| {
                 visit::visit_item(i, cx, v);
-                match *ecx.tcx.items.get(&i.id) {
+                match ecx.tcx.items.get_copy(&i.id) {
                     ast_map::node_item(_, pt) => {
                         encode_info_for_item(ecx, &ebml_w, i,
                                              index, *pt);
@@ -1048,7 +1048,7 @@ fn encode_info_for_items(ecx: @EncodeContext, ebml_w: &writer::Encoder,
             let ebml_w = copy *ebml_w;
             |ni, cx, v| {
                 visit::visit_foreign_item(ni, cx, v);
-                match *ecx.tcx.items.get(&ni.id) {
+                match ecx.tcx.items.get_copy(&ni.id) {
                     ast_map::node_foreign_item(_, abi, _, pt) => {
                         encode_info_for_foreign_item(ecx, &ebml_w, ni,
                                                      index, /*bad*/copy *pt,
diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
index 43fff110a7a..330d60a59d3 100644
--- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs
+++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
@@ -18,6 +18,7 @@ use middle::ty;
 use syntax::ast::{m_const, m_imm, m_mutbl};
 use syntax::ast;
 use syntax::codemap::span;
+use util::ppaux::{note_and_explain_region};
 
 pub fn guarantee_lifetime(bccx: @BorrowckCtxt,
                           item_scope_id: ast::node_id,
@@ -215,13 +216,6 @@ impl GuaranteeLifetimeContext {
             }
         };
 
-        // FIXME(#3511) grow to the nearest cleanup scope---this can
-        // cause observable errors if freezing!
-        if !self.bccx.tcx.region_maps.is_cleanup_scope(root_scope) {
-            debug!("%? is not a cleanup scope, adjusting", root_scope);
-            root_scope = self.bccx.tcx.region_maps.cleanup_scope(root_scope);
-        }
-
         // If we are borrowing the inside of an `@mut` box,
         // we need to dynamically mark it to prevent incompatible
         // borrows from happening later.
@@ -235,6 +229,34 @@ impl GuaranteeLifetimeContext {
             }
         };
 
+        // FIXME(#3511) grow to the nearest cleanup scope---this can
+        // cause observable errors if freezing!
+        if !self.bccx.tcx.region_maps.is_cleanup_scope(root_scope) {
+            debug!("%? is not a cleanup scope, adjusting", root_scope);
+
+            let cleanup_scope =
+                self.bccx.tcx.region_maps.cleanup_scope(root_scope);
+
+            if opt_dyna.is_some() {
+                self.tcx().sess.span_warn(
+                    self.span,
+                    fmt!("Dynamic freeze scope artifically extended \
+                          (see Issue #6248)"));
+                note_and_explain_region(
+                    self.bccx.tcx,
+                    "managed value only needs to be frozen for ",
+                    ty::re_scope(root_scope),
+                    "...");
+                note_and_explain_region(
+                    self.bccx.tcx,
+                    "...but due to Issue #6248, it will be frozen for ",
+                    ty::re_scope(cleanup_scope),
+                    "");
+            }
+
+            root_scope = cleanup_scope;
+        }
+
         // Add a record of what is required
         let rm_key = root_map_key {id: cmt_deref.id, derefs: derefs};
         let root_info = RootInfo {scope: root_scope, freeze: opt_dyna};
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 6a47eedcea8..0bb156dd5f6 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -237,7 +237,7 @@ pub fn check_item_recursion(sess: Session,
             match env.def_map.find(&e.id) {
               Some(&def_const(def_id)) => {
                 if ast_util::is_local(def_id) {
-                  match *env.ast_map.get(&def_id.node) {
+                  match env.ast_map.get_copy(&def_id.node) {
                     ast_map::node_item(it, _) => {
                       (v.visit_item)(it, env, v);
                     }
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 852eb1b50a4..5be0c09f4ae 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -523,7 +523,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
                 }
             }
             pat_enum(_, args) => {
-                match *cx.tcx.def_map.get(&pat_id) {
+                match cx.tcx.def_map.get_copy(&pat_id) {
                     def_const(did) => {
                         let const_expr =
                             lookup_const_by_id(cx.tcx, did).get();
@@ -567,7 +567,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
             }
             pat_struct(_, ref flds, _) => {
                 // Is this a struct or an enum variant?
-                match *cx.tcx.def_map.get(&pat_id) {
+                match cx.tcx.def_map.get_copy(&pat_id) {
                     def_variant(_, variant_id) => {
                         if variant(variant_id) == *ctor_id {
                             // FIXME #4731: Is this right? --pcw
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 199eb274ab9..3afe8c3b9d6 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -128,7 +128,7 @@ fn check_item(item: @item, cx: Context, visitor: visit::vt<Context>) {
                             // Yes, it's a destructor.
                             match self_type.node {
                                 ty_path(_, path_node_id) => {
-                                    let struct_def = *cx.tcx.def_map.get(
+                                    let struct_def = cx.tcx.def_map.get_copy(
                                         &path_node_id);
                                     let struct_did =
                                         ast_util::def_id_of_def(struct_def);
@@ -272,7 +272,7 @@ pub fn check_expr(e: @expr, cx: Context, v: visit::vt<Context>) {
         let ts = /*bad*/ copy **ts;
         let type_param_defs = match e.node {
           expr_path(_) => {
-            let did = ast_util::def_id_of_def(*cx.tcx.def_map.get(&e.id));
+            let did = ast_util::def_id_of_def(cx.tcx.def_map.get_copy(&e.id));
             ty::lookup_item_type(cx.tcx, did).generics.type_param_defs
           }
           _ => {
@@ -333,7 +333,7 @@ fn check_ty(aty: @Ty, cx: Context, v: visit::vt<Context>) {
         for cx.tcx.node_type_substs.find(&id).each |ts| {
             // FIXME(#5562): removing this copy causes a segfault before stage2
             let ts = /*bad*/ copy **ts;
-            let did = ast_util::def_id_of_def(*cx.tcx.def_map.get(&id));
+            let did = ast_util::def_id_of_def(cx.tcx.def_map.get_copy(&id));
             let type_param_defs =
                 ty::lookup_item_type(cx.tcx, did).generics.type_param_defs;
             for vec::each2(ts, *type_param_defs) |&ty, type_param_def| {
@@ -399,7 +399,7 @@ pub fn check_bounds(cx: Context,
 fn is_nullary_variant(cx: Context, ex: @expr) -> bool {
     match ex.node {
       expr_path(_) => {
-        match *cx.tcx.def_map.get(&ex.id) {
+        match cx.tcx.def_map.get_copy(&ex.id) {
           def_variant(edid, vdid) => {
             vec::len(ty::enum_variant_with_id(cx.tcx, edid, vdid).args) == 0u
           }
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index faf4b1c3106..c54ff6075fa 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -696,7 +696,7 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
         for vec::each(vec::append_one(tys, decl.output)) |ty| {
             match ty.node {
               ast::ty_path(_, id) => {
-                match *cx.def_map.get(&id) {
+                match cx.def_map.get_copy(&id) {
                   ast::def_prim_ty(ast::ty_int(ast::ty_i)) => {
                     cx.sess.span_lint(
                         ctypes, id, fn_id,
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 59a6e6469e2..60ce34c3af2 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -469,7 +469,7 @@ fn visit_expr(expr: @expr, self: @mut IrMaps, vt: vt<@mut IrMaps>) {
     match expr.node {
       // live nodes required for uses or definitions of variables:
       expr_path(_) => {
-        let def = *self.tcx.def_map.get(&expr.id);
+        let def = self.tcx.def_map.get_copy(&expr.id);
         debug!("expr %d: path that leads to %?", expr.id, def);
         if moves::moved_variable_node_id_from_def(def).is_some() {
             self.add_live_node_for_node(expr.id, ExprNode(expr.span));
@@ -616,7 +616,7 @@ pub impl Liveness {
     fn variable_from_path(&self, expr: @expr) -> Option<Variable> {
         match expr.node {
           expr_path(_) => {
-            let def = *self.tcx.def_map.get(&expr.id);
+            let def = self.tcx.def_map.get_copy(&expr.id);
             moves::moved_variable_node_id_from_def(def).map(
                 |rdef| self.variable(*rdef, expr.span)
             )
@@ -1338,7 +1338,7 @@ pub impl Liveness {
 
     fn access_path(&self, expr: @expr, succ: LiveNode, acc: uint)
                   -> LiveNode {
-        let def = *self.tcx.def_map.get(&expr.id);
+        let def = self.tcx.def_map.get_copy(&expr.id);
         match moves::moved_variable_node_id_from_def(def) {
           Some(nid) => {
             let ln = self.live_node(expr.id, expr.span);
@@ -1605,7 +1605,7 @@ pub impl Liveness {
     fn check_lvalue(@self, expr: @expr, vt: vt<@Liveness>) {
         match expr.node {
           expr_path(_) => {
-            match *self.tcx.def_map.get(&expr.id) {
+            match self.tcx.def_map.get_copy(&expr.id) {
               def_local(nid, mutbl) => {
                 // Assignment to an immutable variable or argument: only legal
                 // if there is no later assignment. If this local is actually
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 2e5e53654a4..da0a3ba25d0 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -409,7 +409,7 @@ pub impl mem_categorization_ctxt {
           }
 
           ast::expr_path(_) => {
-            let def = *self.tcx.def_map.get(&expr.id);
+            let def = self.tcx.def_map.get_copy(&expr.id);
             self.cat_def(expr.id, expr.span, expr_ty, def)
           }
 
@@ -977,7 +977,7 @@ pub fn field_mutbl(tcx: ty::ctxt,
         }
       }
       ty::ty_enum(*) => {
-        match *tcx.def_map.get(&node_id) {
+        match tcx.def_map.get_copy(&node_id) {
           ast::def_variant(_, variant_id) => {
             for ty::lookup_struct_fields(tcx, variant_id).each |fld| {
                 if fld.ident == f_name {
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index 0daad80af5d..58345302d16 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -441,7 +441,7 @@ pub impl VisitContext {
                         self.move_maps.variable_moves_map.insert(
                             expr.id, entire_expr);
 
-                        let def = *self.tcx.def_map.get(&expr.id);
+                        let def = self.tcx.def_map.get_copy(&expr.id);
                         for moved_variable_node_id_from_def(def).each |&id| {
                             self.move_maps.moved_variables_set.insert(id);
                         }
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index a37ebdcfaa2..0df09553ad0 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -481,7 +481,7 @@ pub fn check_crate(tcx: ty::ctxt,
                     }
                 }
                 expr_path(path) => {
-                    check_path(expr.span, *tcx.def_map.get(&expr.id), path);
+                    check_path(expr.span, tcx.def_map.get_copy(&expr.id), path);
                 }
                 expr_struct(_, ref fields, _) => {
                     match ty::get(ty::expr_ty(tcx, expr)).sty {
@@ -499,7 +499,7 @@ pub fn check_crate(tcx: ty::ctxt,
                         ty_enum(id, _) => {
                             if id.crate != local_crate ||
                                     !privileged_items.contains(&(id.node)) {
-                                match *tcx.def_map.get(&expr.id) {
+                                match tcx.def_map.get_copy(&expr.id) {
                                     def_variant(_, variant_id) => {
                                         for (*fields).each |field| {
                                                 debug!("(privacy checking) \
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 06eb2542235..d23a798b623 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -949,7 +949,7 @@ pub fn determine_rp_in_crate(sess: Session,
         let cx = &mut *cx;
         while cx.worklist.len() != 0 {
             let c_id = cx.worklist.pop();
-            let c_variance = { *cx.region_paramd_items.get(&c_id) };
+            let c_variance = cx.region_paramd_items.get_copy(&c_id);
             // NOTE cleanup scopes cause an exaggerated lock here
             debug!("popped %d from worklist", c_id);
             match cx.dep_map.find(&c_id) {
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 1a81d483dfc..61a8b367d6c 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -280,7 +280,7 @@ pub fn trans_opt(bcx: block, o: &Opt) -> opt_result {
 pub fn variant_opt(bcx: block, pat_id: ast::node_id)
     -> Opt {
     let ccx = bcx.ccx();
-    match *ccx.tcx.def_map.get(&pat_id) {
+    match ccx.tcx.def_map.get_copy(&pat_id) {
         ast::def_variant(enum_id, var_id) => {
             let variants = ty::enum_variants(ccx.tcx, enum_id);
             for vec::each(*variants) |v| {
@@ -516,7 +516,7 @@ pub fn enter_opt<'r>(bcx: block,
         match p.node {
             ast::pat_enum(*) |
             ast::pat_ident(_, _, None) if pat_is_const(tcx.def_map, p) => {
-                let const_def = *tcx.def_map.get(&p.id);
+                let const_def = tcx.def_map.get_copy(&p.id);
                 let const_def_id = ast_util::def_id_of_def(const_def);
                 if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) {
                     Some(~[])
@@ -552,7 +552,7 @@ pub fn enter_opt<'r>(bcx: block,
                 if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
                     // Look up the struct variant ID.
                     let struct_id;
-                    match *tcx.def_map.get(&p.id) {
+                    match tcx.def_map.get_copy(&p.id) {
                         ast::def_variant(_, found_struct_id) => {
                             struct_id = found_struct_id;
                         }
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 47363aa9263..5419628cd95 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2052,7 +2052,7 @@ pub fn trans_tuple_struct(ccx: @CrateContext,
                                              fcx.llretptr.get(),
                                              0,
                                              i);
-        let llarg = match *fcx.llargs.get(&field.node.id) {
+        let llarg = match fcx.llargs.get_copy(&field.node.id) {
             local_mem(x) => x,
             _ => {
                 ccx.tcx.sess.bug(~"trans_tuple_struct: llarg wasn't \
@@ -2141,7 +2141,7 @@ pub fn trans_enum_def(ccx: @CrateContext, enum_definition: &ast::enum_def,
 
 pub fn trans_item(ccx: @CrateContext, item: &ast::item) {
     let _icx = ccx.insn_ctxt("trans_item");
-    let path = match *ccx.tcx.items.get(&item.id) {
+    let path = match ccx.tcx.items.get_copy(&item.id) {
         ast_map::node_item(_, p) => p,
         // tjc: ?
         _ => fail!(~"trans_item"),
@@ -2443,7 +2443,7 @@ pub fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef,
 }
 
 pub fn item_path(ccx: @CrateContext, i: @ast::item) -> path {
-    let base = match *ccx.tcx.items.get(&i.id) {
+    let base = match ccx.tcx.items.get_copy(&i.id) {
         ast_map::node_item(_, p) => p,
             // separate map for paths?
         _ => fail!(~"item_path")
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index acd52907b9f..a2a1f3d8b72 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -424,7 +424,7 @@ pub fn trans_expr_fn(bcx: block,
 
     let Result {bcx: bcx, val: closure} = match sigil {
         ast::BorrowedSigil | ast::ManagedSigil | ast::OwnedSigil => {
-            let cap_vars = *ccx.maps.capture_map.get(&user_id);
+            let cap_vars = ccx.maps.capture_map.get_copy(&user_id);
             let ret_handle = match is_loop_body {Some(x) => x,
                                                  None => None};
             let ClosureResult {llbox, cdata_ty, bcx}
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index 3a331e8791b..dd68670287b 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -158,7 +158,7 @@ pub fn get_const_val(cx: @CrateContext, def_id: ast::def_id) -> ValueRef {
         if !ast_util::is_local(def_id) {
             def_id = inline::maybe_instantiate_inline(cx, def_id, true);
         }
-        match *cx.tcx.items.get(&def_id.node) {
+        match cx.tcx.items.get_copy(&def_id.node) {
             ast_map::node_item(@ast::item {
                 node: ast::item_const(_, subexpr), _
             }, _) => {
@@ -167,7 +167,7 @@ pub fn get_const_val(cx: @CrateContext, def_id: ast::def_id) -> ValueRef {
             _ => cx.tcx.sess.bug(~"expected a const to be an item")
         }
     }
-    *cx.const_values.get(&def_id.node)
+    cx.const_values.get_copy(&def_id.node)
 }
 
 pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
@@ -560,7 +560,7 @@ pub fn trans_const(ccx: @CrateContext, _e: @ast::expr, id: ast::node_id) {
         let g = base::get_item_val(ccx, id);
         // At this point, get_item_val has already translated the
         // constant's initializer to determine its LLVM type.
-        let v = *ccx.const_values.get(&id);
+        let v = ccx.const_values.get_copy(&id);
         llvm::LLVMSetInitializer(g, v);
         llvm::LLVMSetGlobalConstant(g, True);
     }
diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs
index e91bec5efed..b16b7732086 100644
--- a/src/librustc/middle/trans/controlflow.rs
+++ b/src/librustc/middle/trans/controlflow.rs
@@ -193,7 +193,7 @@ pub fn trans_log(log_ex: @ast::expr,
     };
 
     let global = if ccx.module_data.contains_key(&modname) {
-        *ccx.module_data.get(&modname)
+        ccx.module_data.get_copy(&modname)
     } else {
         let s = link::mangle_internal_name_by_path_and_seq(
             ccx, modpath, ~"loglevel");
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 2a2bf7ba4ad..1571fd71152 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -864,7 +864,7 @@ pub fn create_local_var(bcx: block, local: @ast::local)
                 something weird");
       }
       option::None => {
-        match *bcx.fcx.lllocals.get(&local.node.pat.id) {
+        match bcx.fcx.lllocals.get_copy(&local.node.pat.id) {
           local_imm(v) => v,
           _ => bcx.tcx().sess.span_bug(local.span, ~"local is bound to \
                                                      something weird")
@@ -917,7 +917,7 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span)
             };
             update_cache(cache, tg, argument_metadata(mdval));
 
-            let llptr = match *fcx.llargs.get(&arg.id) {
+            let llptr = match fcx.llargs.get_copy(&arg.id) {
               local_mem(v) | local_imm(v) => v,
             };
             let declargs = ~[llmdnode(~[llptr]), mdnode];
@@ -960,7 +960,7 @@ pub fn create_function(fcx: fn_ctxt) -> @Metadata<SubProgramMetadata> {
     let sp = fcx.span.get();
     debug!("%s", cx.sess.codemap.span_to_str(sp));
 
-    let (ident, ret_ty, id) = match *cx.tcx.items.get(&fcx.id) {
+    let (ident, ret_ty, id) = match cx.tcx.items.get_copy(&fcx.id) {
       ast_map::node_item(item, _) => {
         match item.node {
           ast::item_fn(ref decl, _, _, _, _) => {
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index b8cdfeb796d..d961c0705e4 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -1117,7 +1117,7 @@ pub fn with_field_tys<R>(tcx: ty::ctxt,
                         ty.repr(tcx)));
                 }
                 Some(node_id) => {
-                    match *tcx.def_map.get(&node_id) {
+                    match tcx.def_map.get_copy(&node_id) {
                         ast::def_variant(enum_id, variant_id) => {
                             let variant_info = ty::enum_variant_with_id(
                                 tcx, enum_id, variant_id);
@@ -1536,7 +1536,7 @@ fn trans_overloaded_op(bcx: block,
                        ret_ty: ty::t,
                        dest: Dest)
                        -> block {
-    let origin = *bcx.ccx().maps.method_map.get(&expr.id);
+    let origin = bcx.ccx().maps.method_map.get_copy(&expr.id);
     let fty = node_id_type(bcx, expr.callee_id);
     callee::trans_call_inner(bcx,
                              expr.info(),
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index c45ba64c584..f49a7fb0de4 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -724,7 +724,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
             let in_type_size = machine::llbitsize_of_real(ccx, llintype);
             let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
             if in_type_size != out_type_size {
-                let sp = match *ccx.tcx.items.get(&ref_id.get()) {
+                let sp = match ccx.tcx.items.get_copy(&ref_id.get()) {
                     ast_map::node_expr(e) => e.span,
                     _ => fail!(~"transmute has non-expr arg"),
                 };
diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs
index 3ae2421a555..73b79fa37e2 100644
--- a/src/librustc/middle/trans/machine.rs
+++ b/src/librustc/middle/trans/machine.rs
@@ -118,7 +118,7 @@ pub fn llalign_of(cx: @CrateContext, t: TypeRef) -> ValueRef {
 // Computes the size of the data part of an enum.
 pub fn static_size_of_enum(cx: @CrateContext, t: ty::t) -> uint {
     if cx.enum_sizes.contains_key(&t) {
-        return *cx.enum_sizes.get(&t);
+        return cx.enum_sizes.get_copy(&t);
     }
 
     debug!("static_size_of_enum %s", ty_to_str(cx.tcx, t));
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index 86b087b937f..693947d7e99 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -312,7 +312,7 @@ pub fn trans_static_method_callee(bcx: block,
     };
 
     let mname = if method_id.crate == ast::local_crate {
-        match *bcx.tcx().items.get(&method_id.node) {
+        match bcx.tcx().items.get_copy(&method_id.node) {
             ast_map::node_trait_method(trait_method, _, _) => {
                 ast_util::trait_method_to_ty_method(trait_method).ident
             }
@@ -329,7 +329,7 @@ pub fn trans_static_method_callee(bcx: block,
             name=%s", method_id, callee_id, *ccx.sess.str_of(mname));
 
     let vtbls = resolve_vtables_in_fn_ctxt(
-        bcx.fcx, *ccx.maps.vtable_map.get(&callee_id));
+        bcx.fcx, ccx.maps.vtable_map.get_copy(&callee_id));
 
     match vtbls[bound_index] {
         typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
@@ -367,7 +367,7 @@ pub fn method_from_methods(ms: &[@ast::method], name: ast::ident)
 pub fn method_with_name(ccx: @CrateContext, impl_id: ast::def_id,
                         name: ast::ident) -> ast::def_id {
     if impl_id.crate == ast::local_crate {
-        match *ccx.tcx.items.get(&impl_id.node) {
+        match ccx.tcx.items.get_copy(&impl_id.node) {
           ast_map::node_item(@ast::item {
                 node: ast::item_impl(_, _, _, ref ms),
                 _
@@ -385,7 +385,7 @@ pub fn method_with_name_or_default(ccx: @CrateContext,
                                    impl_id: ast::def_id,
                                    name: ast::ident) -> ast::def_id {
     if impl_id.crate == ast::local_crate {
-        match *ccx.tcx.items.get(&impl_id.node) {
+        match ccx.tcx.items.get_copy(&impl_id.node) {
           ast_map::node_item(@ast::item {
                 node: ast::item_impl(_, _, _, ref ms), _
           }, _) => {
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index 98db829370c..e1b81933e68 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -101,12 +101,14 @@ pub fn monomorphic_fn(ccx: @CrateContext,
     let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
     let llitem_ty = tpt.ty;
 
-    let map_node = session::expect(ccx.sess, ccx.tcx.items.find(&fn_id.node),
-     || fmt!("While monomorphizing %?, couldn't find it in the item map \
-        (may have attempted to monomorphize an item defined in a different \
-        crate?)", fn_id));
+    let map_node = session::expect(
+        ccx.sess,
+        ccx.tcx.items.find_copy(&fn_id.node),
+        || fmt!("While monomorphizing %?, couldn't find it in the item map \
+                 (may have attempted to monomorphize an item \
+                 defined in a different crate?)", fn_id));
     // Get the path so that we can create a symbol
-    let (pt, name, span) = match *map_node {
+    let (pt, name, span) = match map_node {
       ast_map::node_item(i, pt) => (pt, i.ident, i.span),
       ast_map::node_variant(ref v, enm, pt) => (pt, (*v).node.name, enm.span),
       ast_map::node_method(m, _, pt) => (pt, m.ident, m.span),
@@ -188,7 +190,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
         self_ty: impl_ty_opt
     });
 
-    let lldecl = match *map_node {
+    let lldecl = match map_node {
       ast_map::node_item(i@@ast::item {
                 node: ast::item_fn(ref decl, _, _, _, ref body),
                 _
diff --git a/src/librustc/middle/trans/reachable.rs b/src/librustc/middle/trans/reachable.rs
index a446408d00a..058ce638030 100644
--- a/src/librustc/middle/trans/reachable.rs
+++ b/src/librustc/middle/trans/reachable.rs
@@ -109,7 +109,8 @@ fn traverse_public_item(cx: @mut ctx, item: @item) {
       item_foreign_mod(ref nm) => {
           if !traverse_exports(cx, item.id) {
               for nm.items.each |item| {
-                  (&mut *cx).rmap.insert(item.id); // NOTE reborrow @mut
+                  let cx = &mut *cx; // NOTE reborrow @mut
+                  cx.rmap.insert(item.id);
               }
           }
       }
@@ -125,17 +126,24 @@ fn traverse_public_item(cx: @mut ctx, item: @item) {
                 m.generics.ty_params.len() > 0u ||
                 attr::find_inline_attr(m.attrs) != attr::ia_none
             {
-                (&mut *cx).rmap.insert(m.id); // NOTE reborrow @mut
+                {
+                    let cx = &mut *cx; // NOTE reborrow @mut
+                    cx.rmap.insert(m.id);
+                }
                 traverse_inline_body(cx, &m.body);
             }
         }
       }
       item_struct(ref struct_def, ref generics) => {
         for struct_def.ctor_id.each |&ctor_id| {
-            (&mut *cx).rmap.insert(ctor_id); // NOTE reborrow @mut
+            let cx = &mut *cx; // NOTE reborrow @mut
+            cx.rmap.insert(ctor_id);
         }
         for struct_def.dtor.each |dtor| {
-            (&mut *cx).rmap.insert(dtor.node.id);
+            {
+                let cx = &mut *cx; // NOTE reborrow @mut
+                cx.rmap.insert(dtor.node.id);
+            }
             if generics.ty_params.len() > 0u ||
                 attr::find_inline_attr(dtor.node.attrs) != attr::ia_none
             {
@@ -156,8 +164,7 @@ fn traverse_public_item(cx: @mut ctx, item: @item) {
 
 fn traverse_ty<'a>(ty: @Ty, cx: @mut ctx<'a>, v: visit::vt<@mut ctx<'a>>) {
     {
-        // FIXME #6021: naming rmap shouldn't be necessary
-        let cx = &mut *cx;
+        let cx = &mut *cx; // NOTE reborrow @mut
         if cx.rmap.contains(&ty.id) { return; }
         cx.rmap.insert(ty.id);
     }
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 7e59f580a2c..5f77173f563 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -274,8 +274,9 @@ pub impl Reflector {
             let repr = adt::represent_type(bcx.ccx(), t);
             let variants = ty::substd_enum_variants(ccx.tcx, did, substs);
             let llptrty = T_ptr(type_of(ccx, t));
-            let (_, opaquety) = *(ccx.tcx.intrinsic_defs.find(&ccx.sess.ident_of(~"Opaque"))
-                                      .expect("Failed to resolve intrinsic::Opaque"));
+            let (_, opaquety) =
+                ccx.tcx.intrinsic_defs.find_copy(&ccx.sess.ident_of(~"Opaque"))
+                .expect("Failed to resolve intrinsic::Opaque");
             let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm });
 
             let make_get_disr = || {
@@ -374,7 +375,7 @@ pub fn emit_calls_to_trait_visit_ty(bcx: block,
     use syntax::parse::token::special_idents::tydesc;
     let final = sub_block(bcx, ~"final");
     assert!(bcx.ccx().tcx.intrinsic_defs.contains_key(&tydesc));
-    let (_, tydesc_ty) = *bcx.ccx().tcx.intrinsic_defs.get(&tydesc);
+    let (_, tydesc_ty) = bcx.ccx().tcx.intrinsic_defs.get_copy(&tydesc);
     let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);
     let mut r = Reflector {
         visitor_val: visitor_val,
diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs
index 33145dd4334..fb2358a57e2 100644
--- a/src/librustc/middle/trans/type_use.rs
+++ b/src/librustc/middle/trans/type_use.rs
@@ -239,18 +239,11 @@ pub fn node_type_needs(cx: Context, use_: uint, id: node_id) {
 }
 
 pub fn mark_for_method_call(cx: Context, e_id: node_id, callee_id: node_id) {
+    let mut opt_static_did = None;
     for cx.ccx.maps.method_map.find(&e_id).each |mth| {
         match mth.origin {
           typeck::method_static(did) => {
-            for cx.ccx.tcx.node_type_substs.find(&callee_id).each |ts| {
-                // FIXME(#5562): removing this copy causes a segfault
-                //               before stage2
-                let ts = /*bad*/ copy **ts;
-                let type_uses = type_uses_for(cx.ccx, did, ts.len());
-                for vec::each2(*type_uses, ts) |uses, subst| {
-                    type_needs(cx, *uses, *subst)
-                }
-            }
+              opt_static_did = Some(did);
           }
           typeck::method_param(typeck::method_param {
               param_num: param,
@@ -262,6 +255,19 @@ pub fn mark_for_method_call(cx: Context, e_id: node_id, callee_id: node_id) {
               | typeck::method_super(*) => (),
         }
     }
+
+    // Note: we do not execute this code from within the each() call
+    // above because the recursive call to `type_needs` can trigger
+    // inlining and hence can cause `method_map` and
+    // `node_type_substs` to be modified.
+    for opt_static_did.each |did| {
+        for cx.ccx.tcx.node_type_substs.find_copy(&callee_id).each |ts| {
+            let type_uses = type_uses_for(cx.ccx, did, ts.len());
+            for vec::each2(*type_uses, ts) |uses, subst| {
+                type_needs(cx, *uses, *subst)
+            }
+        }
+    }
 }
 
 pub fn mark_for_expr(cx: Context, e: @expr) {
@@ -291,12 +297,11 @@ pub fn mark_for_expr(cx: Context, e: @expr) {
         }
       }
       expr_path(_) => {
-        for cx.ccx.tcx.node_type_substs.find(&e.id).each |ts| {
-            // FIXME(#5562): removing this copy causes a segfault before stage2
-            let ts = copy **ts;
-            let id = ast_util::def_id_of_def(*cx.ccx.tcx.def_map.get(&e.id));
+        let opt_ts = cx.ccx.tcx.node_type_substs.find_copy(&e.id);
+        for opt_ts.each |ts| {
+            let id = ast_util::def_id_of_def(cx.ccx.tcx.def_map.get_copy(&e.id));
             let uses_for_ts = type_uses_for(cx.ccx, id, ts.len());
-            for vec::each2(*uses_for_ts, ts) |uses, subst| {
+            for vec::each2(*uses_for_ts, *ts) |uses, subst| {
                 type_needs(cx, *uses, *subst)
             }
         }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index b17dac82048..eac73ce1a2e 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3893,7 +3893,7 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] {
           call eval_const_expr, it should never get called twice for the same
           expr, since check_enum_variants also updates the enum_var_cache
          */
-        match *cx.items.get(&id.node) {
+        match cx.items.get_copy(&id.node) {
           ast_map::node_item(@ast::item {
                     node: ast::item_enum(ref enum_definition, _),
                     _
@@ -4424,7 +4424,7 @@ pub fn get_impl_id(tcx: ctxt, trait_id: def_id, self_ty: t) -> def_id {
 pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) {
     let ty_visitor_name = special_idents::ty_visitor;
     assert!(tcx.intrinsic_traits.contains_key(&ty_visitor_name));
-    let trait_ref = *tcx.intrinsic_traits.get(&ty_visitor_name);
+    let trait_ref = tcx.intrinsic_traits.get_copy(&ty_visitor_name);
     (trait_ref,
      mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, BoxTraitStore, ast::m_imm))
 }
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index 0c9b61164d2..a3bf1a5ef52 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -404,7 +404,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
       }
       ast::pat_enum(*) |
       ast::pat_ident(*) if pat_is_const(tcx.def_map, pat) => {
-        let const_did = ast_util::def_id_of_def(*tcx.def_map.get(&pat.id));
+        let const_did = ast_util::def_id_of_def(tcx.def_map.get_copy(&pat.id));
         let const_tpt = ty::lookup_item_type(tcx, const_did);
         demand::suptype(fcx, pat.span, expected, const_tpt.ty);
         fcx.write_ty(pat.id, const_tpt.ty);
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 70282fdc57c..09022b5829a 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -433,7 +433,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
             assign(self_info.self_id, Some(self_info.self_ty));
             debug!("self is assigned to %s",
                    fcx.infcx().ty_to_str(
-                       *fcx.inh.locals.get(&self_info.self_id)));
+                       fcx.inh.locals.get_copy(&self_info.self_id)));
         }
 
         // Add formal parameters.
@@ -466,7 +466,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
             debug!("Local variable %s is assigned type %s",
                    fcx.pat_to_str(local.node.pat),
                    fcx.infcx().ty_to_str(
-                       *fcx.inh.locals.get(&local.node.id)));
+                       fcx.inh.locals.get_copy(&local.node.id)));
             visit::visit_local(local, e, v);
         };
 
@@ -479,7 +479,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
                 debug!("Pattern binding %s is assigned to %s",
                        *tcx.sess.str_of(path.idents[0]),
                        fcx.infcx().ty_to_str(
-                           *fcx.inh.locals.get(&p.id)));
+                           fcx.inh.locals.get_copy(&p.id)));
               }
               _ => {}
             }
@@ -3492,7 +3492,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
       ~"visit_tydesc" => {
         let tydesc_name = special_idents::tydesc;
         assert!(tcx.intrinsic_defs.contains_key(&tydesc_name));
-        let (_, tydesc_ty) = *tcx.intrinsic_defs.get(&tydesc_name);
+        let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name);
         let (_, visitor_object_ty) = ty::visitor_object_ty(tcx);
         let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
             ty: tydesc_ty,
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index c177d5ab0eb..100e23e024c 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -490,7 +490,7 @@ pub fn early_resolve_expr(ex: @ast::expr,
         for fcx.opt_node_ty_substs(ex.id) |substs| {
             debug!("vtable resolution on parameter bounds for expr %s",
                    ex.repr(fcx.tcx()));
-            let def = *cx.tcx.def_map.get(&ex.id);
+            let def = cx.tcx.def_map.get_copy(&ex.id);
             let did = ast_util::def_id_of_def(def);
             let item_ty = ty::lookup_item_type(cx.tcx, did);
             debug!("early resolve expr: def %? %?, %?, %s", ex.id, did, def,
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index d779c20b3e8..09f0b83e616 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -651,7 +651,7 @@ pub impl CoherenceChecker {
 
     fn get_self_type_for_implementation(&self, implementation: @Impl)
                                      -> ty_param_bounds_and_ty {
-        return *self.crate_context.tcx.tcache.get(&implementation.did);
+        return self.crate_context.tcx.tcache.get_copy(&implementation.did);
     }
 
     // Privileged scope checking
@@ -711,7 +711,7 @@ pub impl CoherenceChecker {
 
     fn trait_ref_to_trait_def_id(&self, trait_ref: @trait_ref) -> def_id {
         let def_map = self.crate_context.tcx.def_map;
-        let trait_def = *def_map.get(&trait_ref.ref_id);
+        let trait_def = def_map.get_copy(&trait_ref.ref_id);
         let trait_id = def_id_of_def(trait_def);
         return trait_id;
     }
@@ -751,7 +751,7 @@ pub impl CoherenceChecker {
                                               -> bool {
         match original_type.node {
             ty_path(_, path_id) => {
-                match *self.crate_context.tcx.def_map.get(&path_id) {
+                match self.crate_context.tcx.def_map.get_copy(&path_id) {
                     def_ty(def_id) | def_struct(def_id) => {
                         if def_id.crate != local_crate {
                             return false;
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 0ffd398d03c..3da6995b423 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -220,7 +220,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
 {
     let tcx = ccx.tcx;
     let region_paramd = tcx.region_paramd_items.find(&trait_id).map(|&x| *x);
-    match *tcx.items.get(&trait_id) {
+    match tcx.items.get_copy(&trait_id) {
         ast_map::node_item(@ast::item {
             node: ast::item_trait(ref generics, _, ref ms),
             _