about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2014-09-01 16:14:56 +1200
committerNick Cameron <ncameron@mozilla.com>2014-09-03 08:29:33 +1200
commite9bd650cad7c519e3f39b8bbed5afeac94daff05 (patch)
tree0d22115081fa8919e4279d942eb689e9f80ab7b1
parentdfbd4669cd0ce6298b5cee7d4b5e1585d8228daa (diff)
downloadrust-e9bd650cad7c519e3f39b8bbed5afeac94daff05.tar.gz
rust-e9bd650cad7c519e3f39b8bbed5afeac94daff05.zip
Schedule cleanup for &* on fat owned pointers
For example `let _x: &Trait = &*(box Foo as Box<Trait>);`. There was a bug where no cleanup would be scheduled by the deref.

No test because cleanup-auto-borrow-obj.rs is a test for this once we remove trait cross-borrowing (done on another branch).
-rw-r--r--src/librustc/middle/trans/datum.rs2
-rw-r--r--src/librustc/middle/trans/expr.rs18
2 files changed, 14 insertions, 6 deletions
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index 2882eaf10be..74093d26fea 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -451,6 +451,8 @@ impl Datum<Expr> {
                                name: &str,
                                expr_id: ast::NodeId)
                                -> DatumBlock<'a, Lvalue> {
+        debug!("to_lvalue_datum self: {}", self.to_string(bcx.ccx()));
+
         assert!(ty::lltype_is_sized(bcx.tcx(), self.ty),
                 "Trying to convert unsized value to lval");
         self.match_kind(
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index ce4c5c9de16..1f91c255ddd 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -2061,11 +2061,17 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
             if ty::type_is_sized(bcx.tcx(), content_ty) {
                 deref_owned_pointer(bcx, expr, datum, content_ty)
             } else {
-                // A fat pointer and an opened DST value have the same represenation
-                // just different types.
-                DatumBlock::new(bcx, Datum::new(datum.val,
-                                                ty::mk_open(bcx.tcx(), content_ty),
-                                                datum.kind))
+                // A fat pointer and an opened DST value have the same
+                // represenation just different types. Since there is no
+                // temporary for `*e` here (because it is unsized), we cannot
+                // emulate the sized object code path for running drop glue and
+                // free. Instead, we schedule cleanup for `e`, turning it into
+                // an lvalue.
+                let datum = unpack_datum!(
+                    bcx, datum.to_lvalue_datum(bcx, "deref", expr.id));
+
+                let datum = Datum::new(datum.val, ty::mk_open(bcx.tcx(), content_ty), LvalueExpr);
+                DatumBlock::new(bcx, datum)
             }
         }
 
@@ -2094,7 +2100,7 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
                 // just different types.
                 DatumBlock::new(bcx, Datum::new(datum.val,
                                                 ty::mk_open(bcx.tcx(), content_ty),
-                                                datum.kind))
+                                                LvalueExpr))
             }
         }