@@ -211,70 +211,13 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
211
211
let mut llargs = Vec :: with_capacity ( arg_count) ;
212
212
213
213
// Prepare the return value destination
214
- let ret_dest = if let Some ( ( ref d, _) ) = * destination {
215
- match * d {
216
- // Handle temporary lvalues, specifically Operand ones, as
217
- // they don't have allocas
218
- mir:: Lvalue :: Temp ( idx) => {
219
- let lvalue_ty = self . mir . lvalue_ty ( bcx. tcx ( ) , d) ;
220
- let ret_ty = lvalue_ty. to_ty ( bcx. tcx ( ) ) ;
221
- match self . temps [ idx as usize ] {
222
- TempRef :: Lvalue ( dest) => {
223
- if fn_ty. ret . is_indirect ( ) {
224
- llargs. push ( dest. llval ) ;
225
- ReturnDest :: Nothing
226
- } else if fn_ty. ret . is_ignore ( ) {
227
- ReturnDest :: Nothing
228
- } else {
229
- ReturnDest :: Store ( dest. llval )
230
- }
231
- }
232
- TempRef :: Operand ( None ) => {
233
- let is_intrinsic = if let Intrinsic = callee. data {
234
- true
235
- } else {
236
- false
237
- } ;
238
-
239
- if fn_ty. ret . is_indirect ( ) {
240
- // Odd, but possible, case, we have an operand temporary,
241
- // but the calling convention has an indirect return.
242
- let tmp = bcx. with_block ( |bcx| {
243
- base:: alloc_ty ( bcx, ret_ty, "tmp_ret" )
244
- } ) ;
245
- llargs. push ( tmp) ;
246
- ReturnDest :: IndirectOperand ( tmp, idx)
247
- } else if is_intrinsic {
248
- // Currently, intrinsics always need a location to store
249
- // the result. so we create a temporary alloca for the
250
- // result
251
- let tmp = bcx. with_block ( |bcx| {
252
- base:: alloc_ty ( bcx, ret_ty, "tmp_ret" )
253
- } ) ;
254
- ReturnDest :: IndirectOperand ( tmp, idx)
255
- } else if fn_ty. ret . is_ignore ( ) {
256
- ReturnDest :: Nothing
257
- } else {
258
- ReturnDest :: DirectOperand ( idx)
259
- }
260
- }
261
- TempRef :: Operand ( Some ( _) ) => {
262
- bug ! ( "lvalue temp already assigned to" ) ;
263
- }
264
- }
265
- }
266
- _ => {
267
- let dest = self . trans_lvalue ( & bcx, d) ;
268
- if fn_ty. ret . is_indirect ( ) {
269
- llargs. push ( dest. llval ) ;
270
- ReturnDest :: Nothing
271
- } else if fn_ty. ret . is_ignore ( ) {
272
- ReturnDest :: Nothing
273
- } else {
274
- ReturnDest :: Store ( dest. llval )
275
- }
276
- }
277
- }
214
+ let ret_dest = if let Some ( ( ref dest, _) ) = * destination {
215
+ let is_intrinsic = if let Intrinsic = callee. data {
216
+ true
217
+ } else {
218
+ false
219
+ } ;
220
+ self . make_return_dest ( & bcx, dest, & fn_ty. ret , & mut llargs, is_intrinsic)
278
221
} else {
279
222
ReturnDest :: Nothing
280
223
} ;
@@ -601,6 +544,57 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
601
544
self . blocks [ bb. index ( ) ] . llbb
602
545
}
603
546
547
+ fn make_return_dest ( & mut self , bcx : & BlockAndBuilder < ' bcx , ' tcx > ,
548
+ dest : & mir:: Lvalue < ' tcx > , fn_ret_ty : & ArgType ,
549
+ llargs : & mut Vec < ValueRef > , is_intrinsic : bool ) -> ReturnDest {
550
+ // If the return is ignored, we can just return a do-nothing ReturnDest
551
+ if fn_ret_ty. is_ignore ( ) {
552
+ return ReturnDest :: Nothing ;
553
+ }
554
+ let dest = match * dest {
555
+ mir:: Lvalue :: Temp ( idx) => {
556
+ let lvalue_ty = self . mir . lvalue_ty ( bcx. tcx ( ) , dest) ;
557
+ let ret_ty = lvalue_ty. to_ty ( bcx. tcx ( ) ) ;
558
+ match self . temps [ idx as usize ] {
559
+ TempRef :: Lvalue ( dest) => dest,
560
+ TempRef :: Operand ( None ) => {
561
+ // Handle temporary lvalues, specifically Operand ones, as
562
+ // they don't have allocas
563
+ return if fn_ret_ty. is_indirect ( ) {
564
+ // Odd, but possible, case, we have an operand temporary,
565
+ // but the calling convention has an indirect return.
566
+ let tmp = bcx. with_block ( |bcx| {
567
+ base:: alloc_ty ( bcx, ret_ty, "tmp_ret" )
568
+ } ) ;
569
+ llargs. push ( tmp) ;
570
+ ReturnDest :: IndirectOperand ( tmp, idx)
571
+ } else if is_intrinsic {
572
+ // Currently, intrinsics always need a location to store
573
+ // the result. so we create a temporary alloca for the
574
+ // result
575
+ let tmp = bcx. with_block ( |bcx| {
576
+ base:: alloc_ty ( bcx, ret_ty, "tmp_ret" )
577
+ } ) ;
578
+ ReturnDest :: IndirectOperand ( tmp, idx)
579
+ } else {
580
+ ReturnDest :: DirectOperand ( idx)
581
+ } ;
582
+ }
583
+ TempRef :: Operand ( Some ( _) ) => {
584
+ bug ! ( "lvalue temp already assigned to" ) ;
585
+ }
586
+ }
587
+ }
588
+ _ => self . trans_lvalue ( bcx, dest)
589
+ } ;
590
+ if fn_ret_ty. is_indirect ( ) {
591
+ llargs. push ( dest. llval ) ;
592
+ ReturnDest :: Nothing
593
+ } else {
594
+ ReturnDest :: Store ( dest. llval )
595
+ }
596
+ }
597
+
604
598
fn trans_transmute ( & mut self , bcx : & BlockAndBuilder < ' bcx , ' tcx > ,
605
599
src : & mir:: Operand < ' tcx > , dst : LvalueRef < ' tcx > ) {
606
600
let mut val = self . trans_operand ( bcx, src) ;
0 commit comments