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 { 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)) } }