@@ -4,6 +4,7 @@ use rustc_middle::ty::{self, Ty, TypeVisitableExt};
4
4
5
5
use crate :: builder:: Builder ;
6
6
use crate :: builder:: expr:: as_place:: { PlaceBase , PlaceBuilder } ;
7
+ use crate :: builder:: matches:: util:: Range ;
7
8
use crate :: builder:: matches:: { FlatPat , MatchPairTree , TestCase } ;
8
9
9
10
impl < ' a , ' tcx > Builder < ' a , ' tcx > {
@@ -60,10 +61,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
60
61
let prefix_valtree = self . simplify_const_pattern_slice_into_valtree ( prefix) ;
61
62
let match_pair = self . valtree_to_match_pair (
62
63
src_path,
63
- prefix. len ( ) as u64 ,
64
64
prefix_valtree,
65
65
place. clone ( ) ,
66
66
elem_ty,
67
+ Range :: from_start ( 0 ..prefix. len ( ) as u64 ) ,
67
68
opt_slice. is_some ( ) || !suffix. is_empty ( ) ,
68
69
) ;
69
70
@@ -89,16 +90,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
89
90
match_pairs. push ( MatchPairTree :: for_pattern ( subslice, subslice_pat, self ) ) ;
90
91
}
91
92
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
+ }
102
118
}
103
119
104
120
fn should_optimize_subslice ( & self , subslice : & [ Box < Pat < ' tcx > > ] ) -> bool {
@@ -141,23 +157,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
141
157
fn valtree_to_match_pair < ' pat > (
142
158
& mut self ,
143
159
source_pattern : & ' pat Pat < ' tcx > ,
144
- subslice_len : u64 ,
145
160
valtree : ty:: ValTree < ' tcx > ,
146
161
place : PlaceBuilder < ' tcx > ,
147
162
elem_ty : Ty < ' tcx > ,
163
+ range : Range ,
148
164
subsliced : bool ,
149
165
) -> MatchPairTree < ' pat , ' tcx > {
150
166
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 ( ) ) ) ;
156
169
157
170
let pat_ty = if subsliced { Ty :: new_slice ( tcx, elem_ty) } else { source_pattern. ty } ;
158
171
let ty_const = ty:: Const :: new ( tcx, ty:: ConstKind :: Value ( const_ty, valtree) ) ;
159
172
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 ) } ;
161
174
let pattern = tcx. arena . alloc ( Pat {
162
175
ty : pat_ty,
163
176
span : source_pattern. span ,
0 commit comments