about summary refs log tree commit diff
path: root/src/rustc/middle
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-03-14 16:50:20 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-03-14 16:50:20 -0700
commit1e0e089185226217a71f50684c11c2e129f12c2e (patch)
tree5eb18de14b324e9e96018768976840a14071dece /src/rustc/middle
parentb516913a5d46dc32d47b7846bb510fc029e660b3 (diff)
downloadrust-1e0e089185226217a71f50684c11c2e129f12c2e.tar.gz
rust-1e0e089185226217a71f50684c11c2e129f12c2e.zip
rustc: Fix a couple of bugs that prevented taking addresses of rvalues
Diffstat (limited to 'src/rustc/middle')
-rw-r--r--src/rustc/middle/region.rs4
-rw-r--r--src/rustc/middle/trans/base.rs9
-rw-r--r--src/rustc/middle/typeck.rs2
3 files changed, 8 insertions, 7 deletions
diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs
index f8aff4cdad1..745b3a837a8 100644
--- a/src/rustc/middle/region.rs
+++ b/src/rustc/middle/region.rs
@@ -254,12 +254,12 @@ fn resolve_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
             }
             visit::visit_expr(expr, cx, visitor);
         }
-        ast::expr_addr_of(_, _) | ast::expr_alt(_, _, _) {
+        ast::expr_addr_of(_, subexpr) | ast::expr_alt(subexpr, _, _) {
             // Record the block that this expression appears in, in case the
             // operand is an rvalue.
             alt cx.parent {
                 pa_block(blk_id) {
-                    cx.region_map.rvalue_to_block.insert(expr.id, blk_id);
+                    cx.region_map.rvalue_to_block.insert(subexpr.id, blk_id);
                 }
                 _ { cx.sess.span_bug(expr.span, "expr outside of block?!"); }
             }
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 016ef5584fa..dc99fd1678a 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -1649,11 +1649,12 @@ fn trans_unary(bcx: block, op: ast::unop, e: @ast::expr,
 }
 
 fn trans_addr_of(cx: block, e: @ast::expr, dest: dest) -> block {
-    // FIXME: This is wrong.
     let {bcx, val, kind} = trans_temp_lval(cx, e);
-    if kind != owned {
-        bcx.sess().span_bug(e.span,
-                            "can't take the address of an rvalue");
+    let ety = expr_ty(cx, e);
+    let is_immediate = ty::type_is_immediate(ety);
+    if (kind == temporary && is_immediate) || kind == owned_imm {
+        let {bcx: bcx2, val: val2} = do_spill(cx, val, ety);
+        bcx = bcx2; val = val2;
     }
     ret store_in_dest(bcx, val, dest);
 }
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index 3ba3064709b..2bb2317ec40 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -2492,7 +2492,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
       ast::expr_alt(discrim, arms, _) {
         bot = check_expr(fcx, discrim);
 
-        let parent_block = tcx.region_map.rvalue_to_block.get(expr.id);
+        let parent_block = tcx.region_map.rvalue_to_block.get(discrim.id);
 
         // Typecheck the patterns first, so that we get types for all the
         // bindings.