@@ -661,40 +661,46 @@ impl Place {
661
661
self . projection . iter ( ) . fold ( Ok ( start_ty) , |place_ty, elem| {
662
662
let ty = place_ty?;
663
663
match elem {
664
- ProjectionElem :: Deref => {
665
- let deref_ty = ty
666
- . kind ( )
667
- . builtin_deref ( true )
668
- . ok_or_else ( || error ! ( "Cannot dereference type: {ty:?}" ) ) ?;
669
- Ok ( deref_ty. ty )
670
- }
664
+ ProjectionElem :: Deref => Self :: deref_ty ( ty) ,
671
665
ProjectionElem :: Field ( _idx, fty) => Ok ( * fty) ,
672
- ProjectionElem :: Index ( _) | ProjectionElem :: ConstantIndex { .. } => ty
673
- . kind ( )
674
- . builtin_index ( )
675
- . ok_or_else ( || error ! ( "Cannot index non-array type: {ty:?}" ) ) ,
666
+ ProjectionElem :: Index ( _) | ProjectionElem :: ConstantIndex { .. } => {
667
+ Self :: index_ty ( ty)
668
+ }
676
669
ProjectionElem :: Subslice { from, to, from_end } => {
677
- let ty_kind = ty. kind ( ) ;
678
- match ty_kind {
679
- TyKind :: RigidTy ( RigidTy :: Slice ( ..) ) => Ok ( ty) ,
680
- TyKind :: RigidTy ( RigidTy :: Array ( inner, _) ) if !from_end => {
681
- Ty :: try_new_array (
682
- inner,
683
- to. checked_sub ( * from)
684
- . ok_or_else ( || error ! ( "Subslice overflow: {from}..{to}" ) ) ?,
685
- )
686
- }
687
- TyKind :: RigidTy ( RigidTy :: Array ( inner, size) ) => {
688
- let size = size. eval_target_usize ( ) ?;
689
- let len = size - from - to;
690
- Ty :: try_new_array ( inner, len)
691
- }
692
- _ => Err ( Error ( format ! ( "Cannot subslice non-array type: `{ty_kind:?}`" ) ) ) ,
693
- }
670
+ Self :: subslice_ty ( ty, from, to, from_end)
694
671
}
695
672
ProjectionElem :: Downcast ( _) => Ok ( ty) ,
696
673
ProjectionElem :: OpaqueCast ( ty) | ProjectionElem :: Subtype ( ty) => Ok ( * ty) ,
697
674
}
698
675
} )
699
676
}
677
+
678
+ fn index_ty ( ty : Ty ) -> Result < Ty , Error > {
679
+ ty. kind ( ) . builtin_index ( ) . ok_or_else ( || error ! ( "Cannot index non-array type: {ty:?}" ) )
680
+ }
681
+
682
+ fn subslice_ty ( ty : Ty , from : & u64 , to : & u64 , from_end : & bool ) -> Result < Ty , Error > {
683
+ let ty_kind = ty. kind ( ) ;
684
+ match ty_kind {
685
+ TyKind :: RigidTy ( RigidTy :: Slice ( ..) ) => Ok ( ty) ,
686
+ TyKind :: RigidTy ( RigidTy :: Array ( inner, _) ) if !from_end => Ty :: try_new_array (
687
+ inner,
688
+ to. checked_sub ( * from) . ok_or_else ( || error ! ( "Subslice overflow: {from}..{to}" ) ) ?,
689
+ ) ,
690
+ TyKind :: RigidTy ( RigidTy :: Array ( inner, size) ) => {
691
+ let size = size. eval_target_usize ( ) ?;
692
+ let len = size - from - to;
693
+ Ty :: try_new_array ( inner, len)
694
+ }
695
+ _ => Err ( Error ( format ! ( "Cannot subslice non-array type: `{ty_kind:?}`" ) ) ) ,
696
+ }
697
+ }
698
+
699
+ fn deref_ty ( ty : Ty ) -> Result < Ty , Error > {
700
+ let deref_ty = ty
701
+ . kind ( )
702
+ . builtin_deref ( true )
703
+ . ok_or_else ( || error ! ( "Cannot dereference type: {ty:?}" ) ) ?;
704
+ Ok ( deref_ty. ty )
705
+ }
700
706
}
0 commit comments