@@ -265,6 +265,48 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
265
265
}
266
266
}
267
267
268
+ // For `move_val_init` we can evaluate the destination address
269
+ // (the first argument) and then trans the source value (the
270
+ // second argument) directly into the resulting destination
271
+ // address.
272
+ if & name[ ..] == "move_val_init" {
273
+ if let callee:: ArgExprs ( ref exprs) = args {
274
+ let ( dest_expr, source_expr) = if exprs. len ( ) != 2 {
275
+ ccx. sess ( ) . bug ( "expected two exprs as arguments for `move_val_init` intrinsic" ) ;
276
+ } else {
277
+ ( & exprs[ 0 ] , & exprs[ 1 ] )
278
+ } ;
279
+ let arg_tys = ty:: erase_late_bound_regions ( bcx. tcx ( ) , & ty:: ty_fn_args ( callee_ty) ) ;
280
+
281
+ // evaluate destination address
282
+ let lldest_addr = unpack_result ! ( bcx, {
283
+ let dest_datum = unpack_datum!( bcx, expr:: trans( bcx, dest_expr) ) ;
284
+ callee:: trans_arg_datum( bcx,
285
+ arg_tys[ 0 ] ,
286
+ dest_datum,
287
+ cleanup:: CustomScope ( cleanup_scope) ,
288
+ callee:: DontAutorefArg )
289
+ } ) ;
290
+
291
+ // `expr::trans_into(bcx, expr, dest)` is equiv to
292
+ //
293
+ // `trans(bcx, expr).store_to_dest(dest)`,
294
+ //
295
+ // which for `dest == expr::SaveIn(addr)`, is equivalent to:
296
+ //
297
+ // `trans(bcx, expr).store_to(bcx, addr)`.
298
+ let lldest = expr:: Dest :: SaveIn ( lldest_addr) ;
299
+ bcx = expr:: trans_into ( bcx, source_expr, lldest) ;
300
+
301
+ let llresult = C_nil ( ccx) ;
302
+ fcx. pop_and_trans_custom_cleanup_scope ( bcx, cleanup_scope) ;
303
+
304
+ return Result :: new ( bcx, llresult) ;
305
+ } else {
306
+ ccx. sess ( ) . bug ( "expected two exprs as arguments for `move_val_init` intrinsic" ) ;
307
+ }
308
+ }
309
+
268
310
// Push the arguments.
269
311
let mut llargs = Vec :: new ( ) ;
270
312
bcx = callee:: trans_args ( bcx,
@@ -356,22 +398,6 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
356
398
let lltp_ty = type_of:: type_of ( ccx, tp_ty) ;
357
399
C_uint ( ccx, machine:: llalign_of_pref ( ccx, lltp_ty) )
358
400
}
359
- ( _, "move_val_init" ) => {
360
- // Create a datum reflecting the value being moved.
361
- // Use `appropriate_mode` so that the datum is by ref
362
- // if the value is non-immediate. Note that, with
363
- // intrinsics, there are no argument cleanups to
364
- // concern ourselves with, so we can use an rvalue datum.
365
- let tp_ty = * substs. types . get ( FnSpace , 0 ) ;
366
- let mode = appropriate_rvalue_mode ( ccx, tp_ty) ;
367
- let src = Datum {
368
- val : llargs[ 1 ] ,
369
- ty : tp_ty,
370
- kind : Rvalue :: new ( mode)
371
- } ;
372
- bcx = src. store_to ( bcx, llargs[ 0 ] ) ;
373
- C_nil ( ccx)
374
- }
375
401
( _, "drop_in_place" ) => {
376
402
let tp_ty = * substs. types . get ( FnSpace , 0 ) ;
377
403
glue:: drop_ty ( bcx, llargs[ 0 ] , tp_ty, call_debug_location) ;
0 commit comments