@@ -11,7 +11,7 @@ use rustc_middle::mir::*;
11
11
use rustc_middle:: thir:: * ;
12
12
use rustc_middle:: ty:: { self , AdtDef , CanonicalUserTypeAnnotation , Ty , Variance } ;
13
13
use rustc_middle:: { bug, span_bug} ;
14
- use rustc_span:: { DesugaringKind , Span } ;
14
+ use rustc_span:: Span ;
15
15
use tracing:: { debug, instrument, trace} ;
16
16
17
17
use crate :: builder:: ForGuard :: { OutsideGuard , RefWithinGuard } ;
@@ -630,80 +630,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
630
630
block. and ( base_place. index ( idx) )
631
631
}
632
632
633
- /// Given a place that's either an array or a slice, returns an operand
634
- /// with the length of the array/slice.
635
- ///
636
- /// For arrays it'll be `Operand::Constant` with the actual length;
637
- /// For slices it'll be `Operand::Move` of a local using `PtrMetadata`.
638
- fn len_of_slice_or_array (
639
- & mut self ,
640
- block : BasicBlock ,
641
- place : Place < ' tcx > ,
642
- span : Span ,
643
- source_info : SourceInfo ,
644
- ) -> Operand < ' tcx > {
645
- let place_ty = place. ty ( & self . local_decls , self . tcx ) . ty ;
646
- let usize_ty = self . tcx . types . usize ;
647
-
648
- match place_ty. kind ( ) {
649
- ty:: Array ( _elem_ty, len_const) => {
650
- // We know how long an array is, so just use that as a constant
651
- // directly -- no locals needed. We do need one statement so
652
- // that borrow- and initialization-checking consider it used,
653
- // though. FIXME: Do we really *need* to count this as a use?
654
- // Could partial array tracking work off something else instead?
655
- self . cfg . push_fake_read ( block, source_info, FakeReadCause :: ForIndex , place) ;
656
- let const_ = Const :: from_ty_const ( * len_const, usize_ty, self . tcx ) ;
657
- Operand :: Constant ( Box :: new ( ConstOperand { span, user_ty : None , const_ } ) )
658
- }
659
- ty:: Slice ( _elem_ty) => {
660
- let ptr_or_ref = if let [ PlaceElem :: Deref ] = place. projection [ ..]
661
- && let local_ty = self . local_decls [ place. local ] . ty
662
- && local_ty. is_trivially_pure_clone_copy ( )
663
- {
664
- // It's extremely common that we have something that can be
665
- // directly passed to `PtrMetadata`, so avoid an unnecessary
666
- // temporary and statement in those cases. Note that we can
667
- // only do that for `Copy` types -- not `&mut [_]` -- because
668
- // the MIR we're building here needs to pass NLL later.
669
- Operand :: Copy ( Place :: from ( place. local ) )
670
- } else {
671
- let len_span = self . tcx . with_stable_hashing_context ( |hcx| {
672
- let span = source_info. span ;
673
- span. mark_with_reason (
674
- None ,
675
- DesugaringKind :: IndexBoundsCheckReborrow ,
676
- span. edition ( ) ,
677
- hcx,
678
- )
679
- } ) ;
680
- let ptr_ty = Ty :: new_imm_ptr ( self . tcx , place_ty) ;
681
- let slice_ptr = self . temp ( ptr_ty, span) ;
682
- self . cfg . push_assign (
683
- block,
684
- SourceInfo { span : len_span, ..source_info } ,
685
- slice_ptr,
686
- Rvalue :: RawPtr ( Mutability :: Not , place) ,
687
- ) ;
688
- Operand :: Move ( slice_ptr)
689
- } ;
690
-
691
- let len = self . temp ( usize_ty, span) ;
692
- self . cfg . push_assign (
693
- block,
694
- source_info,
695
- len,
696
- Rvalue :: UnaryOp ( UnOp :: PtrMetadata , ptr_or_ref) ,
697
- ) ;
698
-
699
- Operand :: Move ( len)
700
- }
701
- _ => {
702
- span_bug ! ( span, "len called on place of type {place_ty:?}" )
703
- }
704
- }
705
- }
706
-
707
633
fn bounds_check (
708
634
& mut self ,
709
635
block : BasicBlock ,
@@ -712,25 +638,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
712
638
expr_span : Span ,
713
639
source_info : SourceInfo ,
714
640
) -> BasicBlock {
715
- let slice = slice. to_place ( self ) ;
641
+ let usize_ty = self . tcx . types . usize ;
642
+ let bool_ty = self . tcx . types . bool ;
643
+ // bounds check:
644
+ let len = self . temp ( usize_ty, expr_span) ;
645
+ let lt = self . temp ( bool_ty, expr_span) ;
716
646
717
647
// len = len(slice)
718
- let len = self . len_of_slice_or_array ( block, slice, expr_span, source_info) ;
719
-
648
+ self . cfg . push_assign ( block, source_info, len, Rvalue :: Len ( slice. to_place ( self ) ) ) ;
720
649
// lt = idx < len
721
- let bool_ty = self . tcx . types . bool ;
722
- let lt = self . temp ( bool_ty, expr_span) ;
723
650
self . cfg . push_assign (
724
651
block,
725
652
source_info,
726
653
lt,
727
654
Rvalue :: BinaryOp (
728
655
BinOp :: Lt ,
729
- Box :: new ( ( Operand :: Copy ( Place :: from ( index) ) , len . to_copy ( ) ) ) ,
656
+ Box :: new ( ( Operand :: Copy ( Place :: from ( index) ) , Operand :: Copy ( len ) ) ) ,
730
657
) ,
731
658
) ;
732
- let msg = BoundsCheck { len, index : Operand :: Copy ( Place :: from ( index) ) } ;
733
-
659
+ let msg = BoundsCheck { len : Operand :: Move ( len) , index : Operand :: Copy ( Place :: from ( index) ) } ;
734
660
// assert!(lt, "...")
735
661
self . assert ( block, Operand :: Move ( lt) , true , msg, expr_span)
736
662
}
0 commit comments