about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-05-01 20:22:08 -0400
committerNiko Matsakis <niko@alum.mit.edu>2013-05-01 20:22:08 -0400
commitef6b24d1350ad658faee68f7eddd2c05a56900ce (patch)
treedd1d450ea607bee75a1f18d06f8e7ca1227d9015
parent14bf5c4fe7eb110fc124a710b40bc7c5a7801e25 (diff)
downloadrust-ef6b24d1350ad658faee68f7eddd2c05a56900ce.tar.gz
rust-ef6b24d1350ad658faee68f7eddd2c05a56900ce.zip
rustc: fix the fact that trans_lvalue rooted twice
-rw-r--r--src/librustc/middle/trans/_match.rs2
-rw-r--r--src/librustc/middle/trans/datum.rs9
-rw-r--r--src/librustc/middle/trans/expr.rs73
3 files changed, 29 insertions, 55 deletions
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index d7f9567c333..be39edd2d9b 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -966,7 +966,7 @@ pub fn root_pats_as_necessary(bcx: block,
 
                 let datum = Datum {val: val, ty: node_id_type(bcx, pat_id),
                                    mode: ByRef, source: ZeroMem};
-                bcx = datum.root(bcx, br.pats[col].span, root_info);
+                bcx = datum.root(bcx, br.pats[col].span, key, root_info);
                 // If we kept going, we'd only re-root the same value, so
                 // return now.
                 return bcx;
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index 94bff65843b..f4fb3b6c6f5 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -517,7 +517,8 @@ pub impl Datum {
         }
     }
 
-    fn root(&self, mut bcx: block, span: span, root_info: RootInfo) -> block {
+    fn root(&self, mut bcx: block, span: span,
+            root_key: root_map_key, root_info: RootInfo) -> block {
         /*!
          *
          * In some cases, borrowck will decide that an @T/@[]/@str
@@ -525,8 +526,8 @@ pub impl Datum {
          * case, we will call this function, which will stash a copy
          * away until we exit the scope `scope_id`. */
 
-        debug!("root(root_info=%?, self=%?)",
-               root_info, self.to_str(bcx.ccx()));
+        debug!("root(root_map_key=%?, root_info=%?, self=%?)",
+               root_key, root_info, self.to_str(bcx.ccx()));
 
         if bcx.sess().trace() {
             trans_trace(
@@ -674,7 +675,7 @@ pub impl Datum {
         let key = root_map_key { id: expr_id, derefs: derefs };
         let bcx = match ccx.maps.root_map.find(&key) {
             None => bcx,
-            Some(&root_info) => self.root(bcx, span, root_info)
+            Some(&root_info) => self.root(bcx, span, key, root_info)
         };
 
         // Perform the write guard, if necessary.
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 166b8bc01f8..a993f781cdb 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -821,57 +821,30 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
 
     trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr)));
 
-    let unrooted_datum = unpack_datum!(bcx, unrooted(bcx, expr));
-
-    // If the lvalue must remain rooted, create a scratch datum, copy
-    // the lvalue in there, and then arrange for it to be cleaned up
-    // at the end of the scope with id `scope_id`:
-    let root_key = root_map_key { id: expr.id, derefs: 0u };
-    for bcx.ccx().maps.root_map.find(&root_key).each |&root_info| {
-        bcx = unrooted_datum.root(bcx, expr.span, *root_info);
-    }
-
-    return DatumBlock {bcx: bcx, datum: unrooted_datum};
-
-    fn unrooted(bcx: block, expr: @ast::expr) -> DatumBlock {
-        /*!
-         *
-         * Translates `expr`.  Note that this version generally
-         * yields an unrooted, unmoved version.  Rooting and possible
-         * moves are dealt with above in trans_lvalue_unadjusted().
-         *
-         * One exception is if `expr` refers to a local variable,
-         * in which case the source may already be FromMovedLvalue
-         * if appropriate.
-         */
-
-        let mut bcx = bcx;
-
-        match expr.node {
-            ast::expr_paren(e) => {
-                return unrooted(bcx, e);
-            }
-            ast::expr_path(_) => {
-                return trans_def_lvalue(bcx, expr, bcx.def(expr.id));
-            }
-            ast::expr_field(base, ident, _) => {
-                return trans_rec_field(bcx, base, ident);
-            }
-            ast::expr_index(base, idx) => {
-                return trans_index(bcx, expr, base, idx);
-            }
-            ast::expr_unary(ast::deref, base) => {
-                let basedatum = unpack_datum!(bcx, trans_to_datum(bcx, base));
-                return basedatum.deref(bcx, base, 0);
-            }
-            _ => {
-                bcx.tcx().sess.span_bug(
-                    expr.span,
-                    fmt!("trans_lvalue reached fall-through case: %?",
-                         expr.node));
-            }
+    return match expr.node {
+        ast::expr_paren(e) => {
+            unrooted(bcx, e)
         }
-    }
+        ast::expr_path(_) => {
+            trans_def_lvalue(bcx, expr, bcx.def(expr.id))
+        }
+        ast::expr_field(base, ident, _) => {
+            trans_rec_field(bcx, base, ident)
+        }
+        ast::expr_index(base, idx) => {
+            trans_index(bcx, expr, base, idx)
+        }
+        ast::expr_unary(ast::deref, base) => {
+            let basedatum = unpack_datum!(bcx, trans_to_datum(bcx, base));
+            basedatum.deref(bcx, base, 0)
+        }
+        _ => {
+            bcx.tcx().sess.span_bug(
+                expr.span,
+                fmt!("trans_lvalue reached fall-through case: %?",
+                     expr.node));
+        }
+    };
 
     fn trans_rec_field(bcx: block,
                        base: @ast::expr,