@@ -429,87 +429,78 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
429
429
let cx = self . cx ;
430
430
let tcx = self . cx . tcx ( ) ;
431
431
432
- let result = match place_ref {
433
- mir:: PlaceRef { local, projection : [ ] } => match self . locals [ local] {
434
- LocalRef :: Place ( place) => {
435
- return place;
436
- }
437
- LocalRef :: UnsizedPlace ( place) => {
438
- return bx. load_operand ( place) . deref ( cx) ;
439
- }
440
- LocalRef :: Operand ( ..) => {
432
+ let mut base = 0 ;
433
+ let mut cg_base = match self . locals [ place_ref. local ] {
434
+ LocalRef :: Place ( place) => place,
435
+ LocalRef :: UnsizedPlace ( place) => bx. load_operand ( place) . deref ( cx) ,
436
+ LocalRef :: Operand ( ..) => {
437
+ if let Some ( elem) = place_ref
438
+ . projection
439
+ . iter ( )
440
+ . enumerate ( )
441
+ . find ( |elem| matches ! ( elem. 1 , mir:: ProjectionElem :: Deref ) )
442
+ {
443
+ base = elem. 0 + 1 ;
444
+ self . codegen_consume (
445
+ bx,
446
+ mir:: PlaceRef { projection : & place_ref. projection [ ..elem. 0 ] , ..place_ref } ,
447
+ )
448
+ . deref ( bx. cx ( ) )
449
+ } else {
441
450
bug ! ( "using operand local {:?} as place" , place_ref) ;
442
451
}
443
- } ,
444
- mir:: PlaceRef { local, projection : [ proj_base @ .., mir:: ProjectionElem :: Deref ] } => {
445
- // Load the pointer from its location.
446
- self . codegen_consume ( bx, mir:: PlaceRef { local, projection : proj_base } )
447
- . deref ( bx. cx ( ) )
448
452
}
449
- mir:: PlaceRef { local, projection : & [ ref proj_base @ .., elem] } => {
450
- // FIXME turn this recursion into iteration
451
- let cg_base =
452
- self . codegen_place ( bx, mir:: PlaceRef { local, projection : proj_base } ) ;
453
-
454
- match elem {
455
- mir:: ProjectionElem :: Deref => bug ! ( ) ,
456
- mir:: ProjectionElem :: Field ( ref field, _) => {
457
- cg_base. project_field ( bx, field. index ( ) )
458
- }
459
- mir:: ProjectionElem :: Index ( index) => {
460
- let index = & mir:: Operand :: Copy ( mir:: Place :: from ( index) ) ;
461
- let index = self . codegen_operand ( bx, index) ;
462
- let llindex = index. immediate ( ) ;
463
- cg_base. project_index ( bx, llindex)
464
- }
465
- mir:: ProjectionElem :: ConstantIndex {
466
- offset,
467
- from_end : false ,
468
- min_length : _,
469
- } => {
470
- let lloffset = bx. cx ( ) . const_usize ( offset as u64 ) ;
471
- cg_base. project_index ( bx, lloffset)
472
- }
473
- mir:: ProjectionElem :: ConstantIndex {
474
- offset,
475
- from_end : true ,
476
- min_length : _,
477
- } => {
478
- let lloffset = bx. cx ( ) . const_usize ( offset as u64 ) ;
479
- let lllen = cg_base. len ( bx. cx ( ) ) ;
480
- let llindex = bx. sub ( lllen, lloffset) ;
481
- cg_base. project_index ( bx, llindex)
482
- }
483
- mir:: ProjectionElem :: Subslice { from, to, from_end } => {
484
- let mut subslice =
485
- cg_base. project_index ( bx, bx. cx ( ) . const_usize ( from as u64 ) ) ;
486
- let projected_ty =
487
- PlaceTy :: from_ty ( cg_base. layout . ty ) . projection_ty ( tcx, elem) . ty ;
488
- subslice. layout = bx. cx ( ) . layout_of ( self . monomorphize ( projected_ty) ) ;
489
-
490
- if subslice. layout . is_unsized ( ) {
491
- assert ! ( from_end, "slice subslices should be `from_end`" ) ;
492
- subslice. llextra = Some ( bx. sub (
493
- cg_base. llextra . unwrap ( ) ,
494
- bx. cx ( ) . const_usize ( ( from as u64 ) + ( to as u64 ) ) ,
495
- ) ) ;
496
- }
497
-
498
- // Cast the place pointer type to the new
499
- // array or slice type (`*[%_; new_len]`).
500
- subslice. llval = bx. pointercast (
501
- subslice. llval ,
502
- bx. cx ( ) . type_ptr_to ( bx. cx ( ) . backend_type ( subslice. layout ) ) ,
503
- ) ;
504
-
505
- subslice
453
+ } ;
454
+ for elem in place_ref. projection [ base..] . iter ( ) {
455
+ cg_base = match elem. clone ( ) {
456
+ mir:: ProjectionElem :: Deref => bx. load_operand ( cg_base) . deref ( bx. cx ( ) ) ,
457
+ mir:: ProjectionElem :: Field ( ref field, _) => {
458
+ cg_base. project_field ( bx, field. index ( ) )
459
+ }
460
+ mir:: ProjectionElem :: Index ( index) => {
461
+ let index = & mir:: Operand :: Copy ( mir:: Place :: from ( index) ) ;
462
+ let index = self . codegen_operand ( bx, index) ;
463
+ let llindex = index. immediate ( ) ;
464
+ cg_base. project_index ( bx, llindex)
465
+ }
466
+ mir:: ProjectionElem :: ConstantIndex { offset, from_end : false , min_length : _ } => {
467
+ let lloffset = bx. cx ( ) . const_usize ( offset as u64 ) ;
468
+ cg_base. project_index ( bx, lloffset)
469
+ }
470
+ mir:: ProjectionElem :: ConstantIndex { offset, from_end : true , min_length : _ } => {
471
+ let lloffset = bx. cx ( ) . const_usize ( offset as u64 ) ;
472
+ let lllen = cg_base. len ( bx. cx ( ) ) ;
473
+ let llindex = bx. sub ( lllen, lloffset) ;
474
+ cg_base. project_index ( bx, llindex)
475
+ }
476
+ mir:: ProjectionElem :: Subslice { from, to, from_end } => {
477
+ let mut subslice = cg_base. project_index ( bx, bx. cx ( ) . const_usize ( from as u64 ) ) ;
478
+ let projected_ty =
479
+ PlaceTy :: from_ty ( cg_base. layout . ty ) . projection_ty ( tcx, elem. clone ( ) ) . ty ;
480
+ subslice. layout = bx. cx ( ) . layout_of ( self . monomorphize ( projected_ty) ) ;
481
+
482
+ if subslice. layout . is_unsized ( ) {
483
+ assert ! ( from_end, "slice subslices should be `from_end`" ) ;
484
+ subslice. llextra = Some ( bx. sub (
485
+ cg_base. llextra . unwrap ( ) ,
486
+ bx. cx ( ) . const_usize ( ( from as u64 ) + ( to as u64 ) ) ,
487
+ ) ) ;
506
488
}
507
- mir:: ProjectionElem :: Downcast ( _, v) => cg_base. project_downcast ( bx, v) ,
489
+
490
+ // Cast the place pointer type to the new
491
+ // array or slice type (`*[%_; new_len]`).
492
+ subslice. llval = bx. pointercast (
493
+ subslice. llval ,
494
+ bx. cx ( ) . type_ptr_to ( bx. cx ( ) . backend_type ( subslice. layout ) ) ,
495
+ ) ;
496
+
497
+ subslice
508
498
}
509
- }
510
- } ;
511
- debug ! ( "codegen_place(place={:?}) => {:?}" , place_ref, result) ;
512
- result
499
+ mir:: ProjectionElem :: Downcast ( _, v) => cg_base. project_downcast ( bx, v) ,
500
+ } ;
501
+ }
502
+ debug ! ( "codegen_place(place={:?}) => {:?}" , place_ref, cg_base) ;
503
+ cg_base
513
504
}
514
505
515
506
pub fn monomorphized_place_ty ( & self , place_ref : mir:: PlaceRef < ' tcx > ) -> Ty < ' tcx > {
0 commit comments