@@ -484,6 +484,7 @@ fn trans_arg_expr(bcx: block,
484
484
{
485
485
let _icx = bcx. insn_ctxt ( "trans_arg_expr" ) ;
486
486
let ccx = bcx. ccx ( ) ;
487
+ let mut bcx = bcx;
487
488
488
489
debug ! ( "trans_arg_expr(formal_ty=(%?,%s), arg_expr=%s, \
489
490
ret_flag=%?)",
@@ -492,97 +493,104 @@ fn trans_arg_expr(bcx: block,
492
493
ret_flag. map( |v| bcx. val_str( v) ) ) ;
493
494
let _indenter = indenter ( ) ;
494
495
495
- // translate the arg expr to a datum
496
- let arg_datumblock = match ret_flag {
497
- None => expr:: trans_to_datum ( bcx, arg_expr) ,
498
-
499
- // If there is a ret_flag, this *must* be a loop body
500
- Some ( _) => {
501
- match arg_expr. node {
502
- ast:: expr_loop_body(
503
- blk @ @{ node : ast:: expr_fn_block( decl, body, cap) , _} ) =>
504
- {
505
- let scratch_ty = expr_ty ( bcx, blk) ;
506
- let scratch = alloc_ty ( bcx, scratch_ty) ;
507
- let arg_ty = expr_ty ( bcx, arg_expr) ;
508
- let proto = ty:: ty_fn_proto ( arg_ty) ;
509
- let bcx = closure:: trans_expr_fn (
510
- bcx, proto, decl, body, blk. id ,
511
- cap, Some ( ret_flag) , expr:: SaveIn ( scratch) ) ;
512
- DatumBlock { bcx : bcx,
513
- datum : Datum { val : scratch,
514
- ty : scratch_ty,
515
- mode : ByRef ,
516
- source : FromRvalue } }
517
- }
518
- _ => {
519
- bcx. sess ( ) . impossible_case (
520
- arg_expr. span , ~"ret_flag with non-loop -\
521
- body expr") ;
522
- }
523
- }
524
- }
525
- } ;
526
- let mut arg_datum = arg_datumblock. datum ;
527
- let mut bcx = arg_datumblock. bcx ;
528
-
529
- debug ! ( " arg datum: %s" , arg_datum. to_str( bcx. ccx( ) ) ) ;
530
-
531
496
// finally, deal with the various modes
532
497
let arg_mode = ty:: resolved_mode ( ccx. tcx , formal_ty. mode ) ;
533
498
let mut val;
534
- if ty:: type_is_bot ( arg_datum. ty ) {
535
- // For values of type _|_, we generate an
536
- // "undef" value, as such a value should never
537
- // be inspected. It's important for the value
538
- // to have type lldestty (the callee's expected type).
539
- let llformal_ty = type_of:: type_of ( ccx, formal_ty. ty ) ;
540
- val = llvm:: LLVMGetUndef ( llformal_ty) ;
541
- } else {
542
- match arg_mode {
543
- ast:: by_ref | ast:: by_mutbl_ref => {
544
- val = arg_datum. to_ref_llval ( bcx) ;
545
- }
499
+ match arg_mode {
500
+ ast:: by_ref | ast:: by_mutbl_ref => {
501
+ let datum = unpack_datum ! ( bcx, {
502
+ trans_arg_expr_to_datum( bcx, arg_expr, ret_flag)
503
+ } ) ;
504
+ val = datum. to_ref_llval ( bcx) ;
505
+ }
546
506
547
- ast:: by_val => {
548
- // NB: avoid running the take glue.
549
- val = arg_datum. to_value_llval ( bcx) ;
550
- }
507
+ ast:: by_val => {
508
+ let datum = unpack_datum ! ( bcx, {
509
+ trans_arg_expr_to_datum( bcx, arg_expr, ret_flag)
510
+ } ) ;
511
+ val = datum. to_value_llval ( bcx) ;
512
+ }
551
513
552
- ast:: by_copy | ast:: by_move => {
553
- let scratch = scratch_datum ( bcx, arg_datum. ty , false ) ;
514
+ ast:: by_copy | ast:: by_move => {
515
+ let scratch = scratch_datum ( bcx, formal_ty. ty , false ) ;
516
+ bcx = trans_arg_expr_into ( bcx, arg_expr, ret_flag,
517
+ expr:: SaveIn ( scratch. val ) ) ;
518
+
519
+ // Technically, ownership of val passes to the callee.
520
+ // However, we must cleanup should we fail before the
521
+ // callee is actually invoked.
522
+ scratch. add_clean ( bcx) ;
523
+ vec:: push ( * temp_cleanups, scratch. val ) ;
524
+ val = scratch. val ;
525
+ }
526
+ }
554
527
555
- if arg_mode == ast :: by_move {
556
- // NDM---Doesn't seem like this should be necessary
557
- if !arg_datum . store_will_move ( ) {
558
- bcx . sess ( ) . span_bug (
559
- arg_expr . span ,
560
- fmt ! ( "move mode but datum will not store: %s" ,
561
- arg_datum . to_str ( bcx. ccx ( ) ) ) ) ;
562
- }
563
- }
528
+ /*
529
+ if formal_ty.ty != arg_datum.ty {
530
+ // this could happen due to e.g. subtyping
531
+ let llformal_ty = type_of::type_of_explicit_arg(ccx, formal_ty);
532
+ debug!("casting actual type (%s) to match formal (%s)" ,
533
+ bcx.val_str(val), bcx.llty_str(llformal_ty));
534
+ val = PointerCast (bcx, val, llformal_ty );
535
+ }
536
+ */
564
537
565
- arg_datum. store_to_datum ( bcx, INIT , scratch) ;
538
+ debug ! ( "--- trans_arg_expr passing %s" , val_str( bcx. ccx( ) . tn, val) ) ;
539
+ return rslt ( bcx, val) ;
566
540
567
- // Technically, ownership of val passes to the callee.
568
- // However, we must cleanup should we fail before the
569
- // callee is actually invoked.
570
- scratch. add_clean ( bcx) ;
571
- vec:: push ( * temp_cleanups, scratch. val ) ;
572
- val = scratch. val ;
573
- }
574
- }
541
+ fn trans_arg_expr_to_datum ( bcx : block ,
542
+ arg_expr : @ast:: expr ,
543
+ ret_flag : Option < ValueRef > ) -> DatumBlock {
544
+ match ret_flag {
545
+ None => {
546
+ expr:: trans_to_datum ( bcx, arg_expr)
547
+ }
575
548
576
- if formal_ty. ty != arg_datum. ty {
577
- // this could happen due to e.g. subtyping
578
- let llformal_ty = type_of:: type_of_explicit_arg ( ccx, formal_ty) ;
579
- debug ! ( "casting actual type (%s) to match formal (%s)" ,
580
- bcx. val_str( val) , bcx. llty_str( llformal_ty) ) ;
581
- val = PointerCast ( bcx, val, llformal_ty) ;
549
+ // If there is a ret_flag, this *must* be a loop body
550
+ Some ( _) => {
551
+ match arg_expr. node {
552
+ ast:: expr_loop_body(
553
+ blk @ @{ node : ast:: expr_fn_block( decl, body,
554
+ cap) , _} ) =>
555
+ {
556
+ let scratch_ty = expr_ty ( bcx, blk) ;
557
+ let scratch = alloc_ty ( bcx, scratch_ty) ;
558
+ let arg_ty = expr_ty ( bcx, arg_expr) ;
559
+ let proto = ty:: ty_fn_proto ( arg_ty) ;
560
+ let bcx = closure:: trans_expr_fn (
561
+ bcx, proto, decl, body, blk. id ,
562
+ cap, Some ( ret_flag) , expr:: SaveIn ( scratch) ) ;
563
+ DatumBlock { bcx : bcx,
564
+ datum : Datum { val : scratch,
565
+ ty : scratch_ty,
566
+ mode : ByRef ,
567
+ source : FromRvalue } }
568
+ }
569
+ _ => {
570
+ bcx. sess ( ) . impossible_case (
571
+ arg_expr. span , ~"ret_flag with non-loop -\
572
+ body expr") ;
573
+ }
574
+ }
575
+ }
582
576
}
583
577
}
584
578
585
- debug ! ( "--- trans_arg_expr passing %s" , val_str( bcx. ccx( ) . tn, val) ) ;
586
- return rslt ( bcx, val) ;
579
+ fn trans_arg_expr_into ( bcx : block ,
580
+ arg_expr : @ast:: expr ,
581
+ ret_flag : Option < ValueRef > ,
582
+ dest : expr:: Dest ) -> block {
583
+ match ret_flag {
584
+ None => {
585
+ expr:: trans_into ( bcx, arg_expr, dest)
586
+ }
587
+
588
+ Some ( _) => {
589
+ let DatumBlock { bcx, datum} =
590
+ trans_arg_expr_to_datum ( bcx, arg_expr, ret_flag) ;
591
+ datum. store_to_dest ( bcx, dest)
592
+ }
593
+ }
594
+ }
587
595
}
588
596
0 commit comments