@@ -1321,7 +1321,9 @@ fn make_take_glue(cx: @block_ctxt, v: ValueRef, t: ty::t) {
1321
1321
bcx = incr_refcnt_of_boxed ( bcx, Load ( bcx, v) ) ;
1322
1322
} else if ty:: type_is_unique_box ( bcx_tcx ( bcx) , t) {
1323
1323
check trans_uniq:: type_is_unique_box ( bcx, t) ;
1324
- bcx = trans_uniq:: duplicate ( bcx, v, t) ;
1324
+ let { bcx: cx , val } = trans_uniq:: duplicate ( bcx, Load ( bcx, v) , t) ;
1325
+ bcx = cx;
1326
+ Store ( bcx, val, v) ;
1325
1327
} else if ty:: type_is_structural ( bcx_tcx ( bcx) , t) {
1326
1328
bcx = iter_structural_ty ( bcx, v, t, take_ty) ;
1327
1329
} else if ty:: type_is_vec ( bcx_tcx ( bcx) , t) {
@@ -1954,6 +1956,27 @@ fn drop_ty(cx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
1954
1956
ret cx;
1955
1957
}
1956
1958
1959
+ fn drop_ty_immediate ( bcx : @block_ctxt , v : ValueRef , t : ty:: t ) -> @block_ctxt {
1960
+ alt ty:: struct ( bcx_tcx ( bcx) , t) {
1961
+ ty:: ty_box ( _) { ret decr_refcnt_maybe_free ( bcx, v, t) ; }
1962
+ ty:: ty_uniq ( _) { ret free_ty ( bcx, v, t) ; }
1963
+ // FIXME A ty_ptr pointing at something that needs drop glue is somehow
1964
+ // marked as needing drop glue. This is probably a mistake.
1965
+ ty:: ty_ptr ( _) { ret bcx; }
1966
+ }
1967
+ }
1968
+
1969
+ fn take_ty_immediate ( bcx : @block_ctxt , v : ValueRef , t : ty:: t ) -> result {
1970
+ alt ty:: struct ( bcx_tcx ( bcx) , t) {
1971
+ ty:: ty_box ( _) { ret rslt ( incr_refcnt_of_boxed ( bcx, v) , v) ; }
1972
+ ty:: ty_uniq ( _) {
1973
+ check trans_uniq:: type_is_unique_box ( bcx, t) ;
1974
+ ret trans_uniq:: duplicate ( bcx, v, t) ;
1975
+ }
1976
+ _ { ret rslt( bcx, v) ; }
1977
+ }
1978
+ }
1979
+
1957
1980
fn free_ty ( cx : @block_ctxt , v : ValueRef , t : ty:: t ) -> @block_ctxt {
1958
1981
if ty:: type_has_pointers ( bcx_tcx ( cx) , t) {
1959
1982
ret call_tydesc_glue ( cx, v, t, abi:: tydesc_field_free_glue) ;
@@ -4059,8 +4082,8 @@ fn get_landing_pad(bcx: @block_ctxt,
4059
4082
let scope_bcx = find_scope_for_lpad ( bcx, have_zero_or_revoke) ;
4060
4083
if scope_bcx. lpad_dirty || have_zero_or_revoke {
4061
4084
let unwind_bcx = new_sub_block_ctxt ( bcx, "unwind" ) ;
4062
- let lpadbb = trans_landing_pad ( unwind_bcx, to_zero, to_revoke) ;
4063
- scope_bcx. lpad = some ( lpadbb ) ;
4085
+ trans_landing_pad ( unwind_bcx, to_zero, to_revoke) ;
4086
+ scope_bcx. lpad = some ( unwind_bcx . llbb ) ;
4064
4087
scope_bcx. lpad_dirty = have_zero_or_revoke;
4065
4088
}
4066
4089
assert option:: is_some ( scope_bcx. lpad ) ;
@@ -4418,10 +4441,15 @@ fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
4418
4441
let ty = ty:: expr_ty ( bcx_tcx ( bcx) , e) ;
4419
4442
alt dest {
4420
4443
by_val( cell) {
4421
- if kind != owned {
4444
+ if kind == temporary {
4422
4445
revoke_clean ( bcx, val) ;
4423
4446
* cell = val;
4447
+ } else if kind == owned_imm {
4448
+ let { bcx: cx , val } = take_ty_immediate ( bcx, val, ty) ;
4449
+ * cell = val;
4450
+ bcx = cx;
4424
4451
} else if ty:: type_is_unique ( bcx_tcx ( bcx) , ty) {
4452
+ // FIXME make vectors immediate again, lose this hack
4425
4453
// Do a song and a dance to work around the fact that take_ty
4426
4454
// for unique boxes overwrites the pointer.
4427
4455
let oldval = Load ( bcx, val) ;
@@ -4723,9 +4751,15 @@ fn init_local(bcx: @block_ctxt, local: @ast::local) -> @block_ctxt {
4723
4751
// This is a local that is kept immediate
4724
4752
none. {
4725
4753
let initexpr = alt local. node . init { some ( { expr, _} ) { expr } } ;
4726
- let val = trans_temp_expr ( bcx, initexpr) ;
4727
- bcx. fcx . lllocals . insert ( local. node . pat . id , local_imm ( val. val ) ) ;
4728
- ret val. bcx ;
4754
+ let { bcx, val, kind} = trans_temp_lval ( bcx, initexpr) ;
4755
+ if kind != temporary {
4756
+ if kind == owned { val = Load ( bcx, val) ; }
4757
+ let rs = take_ty_immediate ( bcx, val, ty) ;
4758
+ bcx = rs. bcx ; val = rs. val ;
4759
+ add_clean_temp ( bcx, val, ty) ;
4760
+ }
4761
+ bcx. fcx . lllocals . insert ( local. node . pat . id , local_imm ( val) ) ;
4762
+ ret bcx;
4729
4763
}
4730
4764
} ;
4731
4765
@@ -4984,8 +5018,7 @@ fn alloc_local(cx: @block_ctxt, local: @ast::local) -> @block_ctxt {
4984
5018
} ;
4985
5019
// Do not allocate space for locals that can be kept immediate.
4986
5020
if is_simple && !bcx_ccx ( cx) . mut_map . contains_key ( local. node . pat . id ) &&
4987
- ty:: type_is_immediate ( bcx_tcx ( cx) , t) &&
4988
- !ty:: type_needs_drop ( bcx_tcx ( cx) , t) {
5021
+ ty:: type_is_immediate ( bcx_tcx ( cx) , t) {
4989
5022
alt local. node . init {
4990
5023
some ( { op: ast:: init_assign. , _} ) { ret cx; }
4991
5024
_ { }
0 commit comments