@@ -4,6 +4,7 @@ use rustc_middle::ty::{self, Ty, TypeVisitableExt};
44
55use crate :: builder:: Builder ;
66use crate :: builder:: expr:: as_place:: { PlaceBase , PlaceBuilder } ;
7+ use crate :: builder:: matches:: util:: Range ;
78use crate :: builder:: matches:: { FlatPat , MatchPairTree , TestCase } ;
89
910impl < ' a , ' tcx > Builder < ' a , ' tcx > {
@@ -60,10 +61,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
6061 let prefix_valtree = self . simplify_const_pattern_slice_into_valtree ( prefix) ;
6162 let match_pair = self . valtree_to_match_pair (
6263 src_path,
63- prefix. len ( ) as u64 ,
6464 prefix_valtree,
6565 place. clone ( ) ,
6666 elem_ty,
67+ Range :: from_start ( 0 ..prefix. len ( ) as u64 ) ,
6768 opt_slice. is_some ( ) || !suffix. is_empty ( ) ,
6869 ) ;
6970
@@ -89,16 +90,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8990 match_pairs. push ( MatchPairTree :: for_pattern ( subslice, subslice_pat, self ) ) ;
9091 }
9192
92- match_pairs. extend ( suffix. iter ( ) . rev ( ) . enumerate ( ) . map ( |( idx, subpattern) | {
93- let end_offset = ( idx + 1 ) as u64 ;
94- let elem = ProjectionElem :: ConstantIndex {
95- offset : if exact_size { min_length - end_offset } else { end_offset } ,
96- min_length,
97- from_end : !exact_size,
98- } ;
99- let place = place. clone_project ( elem) ;
100- MatchPairTree :: for_pattern ( place, subpattern, self )
101- } ) ) ;
93+ if self . should_optimize_subslice ( suffix) {
94+ let elem_ty = suffix[ 0 ] . ty ;
95+ let suffix_valtree = self . simplify_const_pattern_slice_into_valtree ( suffix) ;
96+ let match_pair = self . valtree_to_match_pair (
97+ src_path,
98+ suffix_valtree,
99+ place. clone ( ) ,
100+ elem_ty,
101+ Range :: from_end ( 0 ..suffix. len ( ) as u64 ) ,
102+ true ,
103+ ) ;
104+
105+ match_pairs. push ( match_pair) ;
106+ } else {
107+ match_pairs. extend ( suffix. iter ( ) . rev ( ) . enumerate ( ) . map ( |( idx, subpattern) | {
108+ let end_offset = ( idx + 1 ) as u64 ;
109+ let elem = ProjectionElem :: ConstantIndex {
110+ offset : if exact_size { min_length - end_offset } else { end_offset } ,
111+ min_length,
112+ from_end : !exact_size,
113+ } ;
114+ let place = place. clone_project ( elem) ;
115+ MatchPairTree :: for_pattern ( place, subpattern, self )
116+ } ) ) ;
117+ }
102118 }
103119
104120 fn should_optimize_subslice ( & self , subslice : & [ Box < Pat < ' tcx > > ] ) -> bool {
@@ -141,23 +157,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
141157 fn valtree_to_match_pair < ' pat > (
142158 & mut self ,
143159 source_pattern : & ' pat Pat < ' tcx > ,
144- subslice_len : u64 ,
145160 valtree : ty:: ValTree < ' tcx > ,
146161 place : PlaceBuilder < ' tcx > ,
147162 elem_ty : Ty < ' tcx > ,
163+ range : Range ,
148164 subsliced : bool ,
149165 ) -> MatchPairTree < ' pat , ' tcx > {
150166 let tcx = self . tcx ;
151- let const_ty = Ty :: new_imm_ref (
152- tcx,
153- tcx. lifetimes . re_erased ,
154- Ty :: new_array ( tcx, elem_ty, subslice_len) ,
155- ) ;
167+ let const_ty =
168+ Ty :: new_imm_ref ( tcx, tcx. lifetimes . re_erased , Ty :: new_array ( tcx, elem_ty, range. len ( ) ) ) ;
156169
157170 let pat_ty = if subsliced { Ty :: new_slice ( tcx, elem_ty) } else { source_pattern. ty } ;
158171 let ty_const = ty:: Const :: new ( tcx, ty:: ConstKind :: Value ( const_ty, valtree) ) ;
159172 let value = Const :: Ty ( const_ty, ty_const) ;
160- let test_case = TestCase :: Constant { value, range : subsliced. then ( || 0 ..subslice_len ) } ;
173+ let test_case = TestCase :: Constant { value, range : subsliced. then_some ( range ) } ;
161174 let pattern = tcx. arena . alloc ( Pat {
162175 ty : pat_ty,
163176 span : source_pattern. span ,
0 commit comments