@@ -3259,6 +3259,45 @@ fn copy_val(&@block_ctxt cx,
3259
3259
fail;
3260
3260
}
3261
3261
3262
+ // This works like copy_val, except that it deinitializes the source.
3263
+ // Since it needs to zero out the source, src also needs to be an lval.
3264
+ // FIXME: We always zero out the source. Ideally we would detect the
3265
+ // case where a variable is always deinitialized by block exit and thus
3266
+ // doesn't need to be dropped.
3267
+ fn move_val( & @block_ctxt cx,
3268
+ copy_action action,
3269
+ ValueRef dst,
3270
+ ValueRef src,
3271
+ & ty:: t t) -> result {
3272
+ if ( ty:: type_is_scalar( cx. fcx. lcx. ccx. tcx, t) ||
3273
+ ty:: type_is_native( cx. fcx. lcx. ccx. tcx, t) ) {
3274
+ ret res( cx, cx. build. Store ( src, dst) ) ;
3275
+ } else if ( ty:: type_is_nil( cx. fcx. lcx. ccx. tcx, t) ||
3276
+ ty:: type_is_bot( cx. fcx. lcx. ccx. tcx, t) ) {
3277
+ ret res( cx, C_nil ( ) ) ;
3278
+
3279
+ } else if ( ty:: type_is_boxed( cx. fcx. lcx. ccx. tcx, t) ) {
3280
+ if ( action == DROP_EXISTING ) {
3281
+ cx = drop_ty( cx, cx. build. Load ( dst) , t) . bcx;
3282
+ }
3283
+ auto r = res( cx, cx. build. Store ( cx. build. Load ( src) , dst) ) ;
3284
+ ret zero_alloca( r. bcx, src, t) ;
3285
+
3286
+ } else if ( ty:: type_is_structural( cx. fcx. lcx. ccx. tcx, t) ||
3287
+ ty:: type_has_dynamic_size( cx. fcx. lcx. ccx. tcx, t) ) {
3288
+ if ( action == DROP_EXISTING ) {
3289
+ cx = drop_ty( cx, dst, t) . bcx;
3290
+ }
3291
+ auto r = memmove_ty( cx, dst, cx. build. Load ( src) , t) ;
3292
+ ret zero_alloca( r. bcx, src, t) ;
3293
+ }
3294
+
3295
+ cx. fcx. lcx. ccx. sess. bug( "unexpected type in trans:: move_val: " +
3296
+ ty:: ty_to_str( cx. fcx. lcx. ccx. tcx, t) ) ;
3297
+ fail;
3298
+ }
3299
+
3300
+
3262
3301
fn trans_lit( & @crate_ctxt cx, & ast:: lit lit, & ast:: ann ann) -> ValueRef {
3263
3302
alt ( lit. node) {
3264
3303
case ( ast:: lit_int( ?i) ) {
@@ -5504,12 +5543,11 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output)
5504
5543
auto lhs_res = trans_lval( cx, dst) ;
5505
5544
assert ( lhs_res. is_mem) ;
5506
5545
* ( lhs_res. res. bcx) = rec( sp=src. span with * ( lhs_res. res. bcx) ) ;
5507
- auto rhs_res = trans_expr ( lhs_res. res. bcx, src) ;
5546
+ auto rhs_res = trans_lval ( lhs_res. res. bcx, src) ;
5508
5547
auto t = node_ann_type( cx. fcx. lcx. ccx, ann) ;
5509
5548
// FIXME: calculate copy init-ness in typestate.
5510
- // FIXME: do all of the special move stuff
5511
- ret copy_ty( rhs_res. bcx, DROP_EXISTING ,
5512
- lhs_res. res. val, rhs_res. val, t) ;
5549
+ ret move_val( rhs_res. res. bcx, DROP_EXISTING ,
5550
+ lhs_res. res. val, rhs_res. res. val, t) ;
5513
5551
}
5514
5552
5515
5553
case ( ast:: expr_assign( ?dst, ?src, ?ann) ) {
0 commit comments