@@ -484,7 +484,6 @@ 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;
488
487
489
488
debug ! ( "trans_arg_expr(formal_ty=(%?,%s), arg_expr=%s, \
490
489
ret_flag=%?)",
@@ -493,104 +492,97 @@ fn trans_arg_expr(bcx: block,
493
492
ret_flag. map( |v| bcx. val_str( v) ) ) ;
494
493
let _indenter = indenter ( ) ;
495
494
496
- // finally, deal with the various modes
497
- let arg_mode = ty :: resolved_mode ( ccx . tcx , formal_ty . mode ) ;
498
- let mut val ;
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
- }
506
-
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
- }
513
-
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 ;
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
+ }
525
524
}
526
- }
525
+ } ;
526
+ let mut arg_datum = arg_datumblock. datum ;
527
+ let mut bcx = arg_datumblock. bcx ;
527
528
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
- */
529
+ debug ! ( " arg datum: %s" , arg_datum. to_str( bcx. ccx( ) ) ) ;
537
530
538
- debug ! ( "--- trans_arg_expr passing %s" , val_str( bcx. ccx( ) . tn, val) ) ;
539
- return rslt ( bcx, val) ;
531
+ // finally, deal with the various modes
532
+ let arg_mode = ty:: resolved_mode ( ccx. tcx , formal_ty. mode ) ;
533
+ 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
+ }
540
546
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
+ ast:: by_val => {
548
+ // NB: avoid running the take glue.
549
+ val = arg_datum. to_value_llval ( bcx) ;
547
550
}
548
551
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") ;
552
+ ast:: by_copy | ast:: by_move => {
553
+ let scratch = scratch_datum ( bcx, arg_datum. ty , false ) ;
554
+
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( ) ) ) ) ;
573
562
}
574
563
}
575
- }
576
- }
577
- }
578
564
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
- }
565
+ arg_datum. store_to_datum ( bcx, INIT , scratch) ;
587
566
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
- }
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
+ }
575
+
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) ;
593
582
}
594
583
}
584
+
585
+ debug ! ( "--- trans_arg_expr passing %s" , val_str( bcx. ccx( ) . tn, val) ) ;
586
+ return rslt ( bcx, val) ;
595
587
}
596
588
0 commit comments