@@ -5564,9 +5564,10 @@ fn trans_arg_expr(&@block_ctxt cx, &ty::arg arg, TypeRef lldestty0,
5564
5564
val = do_spill( lv. res. bcx, lv. res. val) ;
5565
5565
}
5566
5566
} else { auto re = trans_expr( bcx, e) ; val = re. val; bcx = re. bcx; }
5567
+ auto is_bot = ty:: type_is_bot( cx. fcx. lcx. ccx. tcx, e_ty) ;
5567
5568
5568
5569
// Make a copy here if the type is structural and we're passing by value.
5569
- if ( arg. mode == ty:: mo_val) {
5570
+ if ( arg. mode == ty:: mo_val && !is_bot ) {
5570
5571
if ( ty:: type_owns_heap_mem( cx. fcx. lcx. ccx. tcx, e_ty) ) {
5571
5572
auto rslt = alloc_ty( bcx, e_ty) ;
5572
5573
bcx = rslt. bcx;
@@ -5579,7 +5580,7 @@ fn trans_arg_expr(&@block_ctxt cx, &ty::arg arg, TypeRef lldestty0,
5579
5580
}
5580
5581
}
5581
5582
5582
- if ( ty :: type_is_bot ( cx . fcx . lcx . ccx . tcx , e_ty ) ) {
5583
+ if ( is_bot ) {
5583
5584
// For values of type _|_, we generate an
5584
5585
// "undef" value, as such a value should never
5585
5586
// be inspected. It's important for the value
@@ -5747,25 +5748,30 @@ fn trans_call(&@block_ctxt cx, &@ast::expr f, &option::t[ValueRef] lliterbody,
5747
5748
}
5748
5749
*/
5749
5750
5750
- bcx. build. FastCall ( faddr, llargs) ;
5751
+ /* If the block is terminated,
5752
+ then one or more of the args has
5753
+ type _|_. Since that means it diverges, the code
5754
+ for the call itself is unreachable. */
5751
5755
auto retval = C_nil ( ) ;
5752
- alt ( lliterbody) {
5753
- case ( none) {
5754
- if ( !ty:: type_is_nil( cx. fcx. lcx. ccx. tcx, ret_ty) ) {
5755
- retval = load_if_immediate( bcx, llretslot, ret_ty) ;
5756
- // Retval doesn't correspond to anything really tangible in
5757
- // the frame, but it's a ref all the same, so we put a note
5758
- // here to drop it when we're done in this scope.
5759
-
5760
- find_scope_cx( cx) . cleanups +=
5761
- [ clean( bind drop_ty( _, retval, ret_ty) ) ] ;
5756
+ if ( !bcx. build. is_terminated( ) ) {
5757
+ bcx. build. FastCall ( faddr, llargs) ;
5758
+ alt ( lliterbody) {
5759
+ case ( none) {
5760
+ if ( !ty:: type_is_nil( cx. fcx. lcx. ccx. tcx, ret_ty) ) {
5761
+ retval = load_if_immediate( bcx, llretslot, ret_ty) ;
5762
+ // Retval doesn't correspond to anything really tangible
5763
+ // in the frame, but it's a ref all the same, so we put a
5764
+ // note here to drop it when we're done in this scope.
5765
+
5766
+ find_scope_cx( cx) . cleanups +=
5767
+ [ clean( bind drop_ty( _, retval, ret_ty) ) ] ;
5768
+ }
5769
+ }
5770
+ case ( some( _) ) {
5771
+ // If there was an lliterbody, it means we were calling an
5772
+ // iter, and we are *not* the party using its 'output' value,
5773
+ // we should ignore llretslot.
5762
5774
}
5763
- }
5764
- case ( some( _) ) {
5765
- // If there was an lliterbody, it means we were calling an
5766
- // iter, and we are *not* the party using its 'output' value,
5767
- // we should ignore llretslot.
5768
-
5769
5775
}
5770
5776
}
5771
5777
ret rslt( bcx, retval) ;
0 commit comments