@@ -1420,7 +1420,7 @@ fn make_drop_glue(cx: &@block_ctxt, v0: ValueRef, t: &ty::t) {
1420
1420
maybe_free_ivec_heap_part ( rslt. bcx , v1, tm. ty )
1421
1421
}
1422
1422
ty:: ty_box ( _) { decr_refcnt_maybe_free ( cx, v0, v0, t) }
1423
- ty:: ty_uniq ( _) { fail "drop uniq unimplemented" ; }
1423
+ ty:: ty_uniq ( _) { trans_shared_free ( cx , cx . build . Load ( v0 ) ) }
1424
1424
ty:: ty_obj ( _) {
1425
1425
let box_cell =
1426
1426
cx. build . GEP ( v0, ~[ C_int ( 0 ) , C_int ( abi:: obj_field_box) ] ) ;
@@ -2311,6 +2311,7 @@ fn copy_val(cx: &@block_ctxt, action: copy_action, dst: ValueRef,
2311
2311
// FIXME: We always zero out the source. Ideally we would detect the
2312
2312
// case where a variable is always deinitialized by block exit and thus
2313
2313
// doesn't need to be dropped.
2314
+ // FIXME: This can return only a block_ctxt, not a result.
2314
2315
fn move_val ( cx : @block_ctxt , action : copy_action , dst : ValueRef ,
2315
2316
src : & lval_result , t : & ty:: t ) -> result {
2316
2317
let src_val = src. res . val ;
@@ -2322,18 +2323,18 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
2322
2323
} else if ( ty:: type_is_nil ( bcx_tcx ( cx) , t) ||
2323
2324
ty:: type_is_bot ( bcx_tcx ( cx) , t) ) {
2324
2325
ret rslt ( cx, C_nil ( ) ) ;
2325
- } else if ( ty:: type_is_boxed ( bcx_tcx ( cx) , t) ) {
2326
+ } else if ( ty:: type_is_unique ( bcx_tcx ( cx) , t) ||
2327
+ ty:: type_is_boxed ( bcx_tcx ( cx) , t) ) {
2326
2328
if src. is_mem { src_val = cx. build . Load ( src_val) ; }
2327
2329
if action == DROP_EXISTING {
2328
2330
cx = drop_ty ( cx, cx. build . Load ( dst) , t) . bcx ;
2329
2331
}
2330
2332
cx. build . Store ( src_val, dst) ;
2331
- if src. is_mem {
2332
- ret zero_alloca ( cx, src. res . val , t) ;
2333
- } else { // It must be a temporary
2334
- revoke_clean ( cx, src_val) ;
2335
- ret rslt( cx, C_nil ( ) ) ;
2336
- }
2333
+ if src. is_mem { ret zero_alloca ( cx, src. res . val , t) ; }
2334
+
2335
+ // If we're here, it must be a temporary.
2336
+ revoke_clean ( cx, src_val) ;
2337
+ ret rslt( cx, C_nil ( ) ) ;
2337
2338
} else if ( ty:: type_is_structural ( bcx_tcx ( cx) , t) ||
2338
2339
ty:: type_has_dynamic_size ( bcx_tcx ( cx) , t) ) {
2339
2340
if action == DROP_EXISTING { cx = drop_ty ( cx, dst, t) . bcx ; }
@@ -2356,7 +2357,8 @@ fn move_val_if_temp(cx: @block_ctxt, action: copy_action, dst: ValueRef,
2356
2357
if src. is_mem {
2357
2358
ret copy_val ( cx, action, dst, load_if_immediate ( cx, src. res . val , t) ,
2358
2359
t) ;
2359
- } else { ret move_val ( cx, action, dst, src, t) ; }
2360
+ }
2361
+ ret move_val( cx, action, dst, src, t) ;
2360
2362
}
2361
2363
2362
2364
fn trans_lit_istr ( cx : & @block_ctxt , s : str ) -> result {
@@ -4092,6 +4094,7 @@ fn trans_lval_gen(cx: &@block_ctxt, e: &@ast::expr) -> lval_result {
4092
4094
} ;
4093
4095
ret lval_mem( sub. bcx , val) ;
4094
4096
}
4097
+ ast:: expr_uniq ( contents) { ret trans_uniq ( cx, contents) ; }
4095
4098
ast:: expr_self_method ( ident) {
4096
4099
alt { cx. fcx . llself } {
4097
4100
some ( pair) {
@@ -5346,6 +5349,25 @@ fn trans_put(cx: &@block_ctxt, e: &option::t[@ast::expr]) -> result {
5346
5349
ret rslt( bcx, C_nil ( ) ) ;
5347
5350
}
5348
5351
5352
+ fn trans_uniq ( cx : & @block_ctxt , contents : & @ast:: expr ) -> lval_result {
5353
+ let bcx = cx;
5354
+
5355
+ let contents_ty = ty:: expr_ty ( bcx_tcx ( bcx) , contents) ;
5356
+ let r = size_of ( bcx, contents_ty) ;
5357
+ bcx = r. bcx ;
5358
+ let llsz = r. val ;
5359
+
5360
+ let llptrty = T_ptr ( type_of_or_i8 ( bcx, contents_ty) ) ;
5361
+
5362
+ r = trans_shared_malloc ( bcx, llptrty, llsz) ;
5363
+ bcx = r. bcx ;
5364
+ let llptrptr = r. val ;
5365
+
5366
+ let llptr = bcx. build . Load ( llptrptr) ;
5367
+ r = trans_expr_out ( bcx, contents, save_in ( llptr) ) ;
5368
+ ret lval_val( r. bcx , llptrptr) ;
5369
+ }
5370
+
5349
5371
fn trans_break_cont ( sp : & span , cx : & @block_ctxt , to_end : bool ) -> result {
5350
5372
let bcx = cx;
5351
5373
// Locate closest loop block, outputting cleanup as we go.
0 commit comments