@@ -12,59 +12,58 @@ use crate::builder::matches::{
1212 FlatPat , MatchPairTree , PatConstKind , PatternExtraData , SliceLenOp , TestableCase ,
1313} ;
1414
15- impl < ' a , ' tcx > Builder < ' a , ' tcx > {
16- /// Builds [`MatchPairTree`] subtrees for the prefix/middle/suffix parts of an
17- /// array pattern or slice pattern, and adds those trees to `match_pairs`.
18- ///
19- /// Used internally by [`MatchPairTree::for_pattern`].
20- fn prefix_slice_suffix (
21- & mut self ,
22- match_pairs : & mut Vec < MatchPairTree < ' tcx > > ,
23- extra_data : & mut PatternExtraData < ' tcx > ,
24- place : & PlaceBuilder < ' tcx > ,
25- array_len : Option < u64 > ,
26- prefix : & [ Pat < ' tcx > ] ,
27- opt_slice : & Option < Box < Pat < ' tcx > > > ,
28- suffix : & [ Pat < ' tcx > ] ,
29- ) {
30- let prefix_len = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
31- let suffix_len = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
32-
33- // For slice patterns with a `..` followed by 0 or more suffix subpatterns,
34- // the actual slice index of those subpatterns isn't statically known, so
35- // we have to index them relative to the end of the slice.
36- //
37- // For array patterns, all subpatterns are indexed relative to the start.
38- let ( min_length, is_array) = match array_len {
39- Some ( len) => ( len, true ) ,
40- None => ( prefix_len + suffix_len, false ) ,
41- } ;
42-
43- for ( offset, subpattern) in ( 0u64 ..) . zip ( prefix) {
44- let elem = ProjectionElem :: ConstantIndex { offset, min_length, from_end : false } ;
45- let place = place. clone_project ( elem) ;
46- MatchPairTree :: for_pattern ( place, subpattern, self , match_pairs, extra_data)
47- }
15+ /// For an array or slice pattern's subpatterns (prefix/slice/suffix), returns a list
16+ /// of those subpatterns, each paired with a suitably-projected [`PlaceBuilder`].
17+ fn prefix_slice_suffix < ' a , ' tcx > (
18+ place : & PlaceBuilder < ' tcx > ,
19+ array_len : Option < u64 > , // Some for array patterns; None for slice patterns
20+ prefix : & ' a [ Pat < ' tcx > ] ,
21+ opt_slice : & ' a Option < Box < Pat < ' tcx > > > ,
22+ suffix : & ' a [ Pat < ' tcx > ] ,
23+ ) -> Vec < ( PlaceBuilder < ' tcx > , & ' a Pat < ' tcx > ) > {
24+ let prefix_len = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
25+ let suffix_len = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
26+
27+ let mut output_pairs =
28+ Vec :: with_capacity ( prefix. len ( ) + usize:: from ( opt_slice. is_some ( ) ) + suffix. len ( ) ) ;
29+
30+ // For slice patterns with a `..` followed by 0 or more suffix subpatterns,
31+ // the actual slice index of those subpatterns isn't statically known, so
32+ // we have to index them relative to the end of the slice.
33+ //
34+ // For array patterns, all subpatterns are indexed relative to the start.
35+ let ( min_length, is_array) = match array_len {
36+ Some ( len) => ( len, true ) ,
37+ None => ( prefix_len + suffix_len, false ) ,
38+ } ;
39+
40+ for ( offset, prefix_subpat) in ( 0u64 ..) . zip ( prefix) {
41+ let elem = ProjectionElem :: ConstantIndex { offset, min_length, from_end : false } ;
42+ let subplace = place. clone_project ( elem) ;
43+ output_pairs. push ( ( subplace, prefix_subpat) ) ;
44+ }
4845
49- if let Some ( subslice_pat) = opt_slice {
50- let subslice = place. clone_project ( PlaceElem :: Subslice {
51- from : prefix_len,
52- to : if is_array { min_length - suffix_len } else { suffix_len } ,
53- from_end : !is_array,
54- } ) ;
55- MatchPairTree :: for_pattern ( subslice, subslice_pat, self , match_pairs, extra_data) ;
56- }
46+ if let Some ( slice_subpat) = opt_slice {
47+ let elem = PlaceElem :: Subslice {
48+ from : prefix_len,
49+ to : if is_array { min_length - suffix_len } else { suffix_len } ,
50+ from_end : !is_array,
51+ } ;
52+ let subplace = place. clone_project ( elem) ;
53+ output_pairs. push ( ( subplace, slice_subpat) ) ;
54+ }
5755
58- for ( end_offset, subpattern) in ( 1u64 ..) . zip ( suffix. iter ( ) . rev ( ) ) {
59- let elem = ProjectionElem :: ConstantIndex {
60- offset : if is_array { min_length - end_offset } else { end_offset } ,
61- min_length,
62- from_end : !is_array,
63- } ;
64- let place = place. clone_project ( elem) ;
65- MatchPairTree :: for_pattern ( place, subpattern, self , match_pairs, extra_data)
66- }
56+ for ( offset_from_end, suffix_subpat) in ( 1u64 ..) . zip ( suffix. iter ( ) . rev ( ) ) {
57+ let elem = ProjectionElem :: ConstantIndex {
58+ offset : if is_array { min_length - offset_from_end } else { offset_from_end } ,
59+ min_length,
60+ from_end : !is_array,
61+ } ;
62+ let subplace = place. clone_project ( elem) ;
63+ output_pairs. push ( ( subplace, suffix_subpat) ) ;
6764 }
65+
66+ output_pairs
6867}
6968
7069impl < ' tcx > MatchPairTree < ' tcx > {
@@ -221,15 +220,11 @@ impl<'tcx> MatchPairTree<'tcx> {
221220 _ => None ,
222221 } ;
223222 if let Some ( array_len) = array_len {
224- cx. prefix_slice_suffix (
225- & mut subpairs,
226- extra_data,
227- & place_builder,
228- Some ( array_len) ,
229- prefix,
230- slice,
231- suffix,
232- ) ;
223+ for ( subplace, subpat) in
224+ prefix_slice_suffix ( & place_builder, Some ( array_len) , prefix, slice, suffix)
225+ {
226+ MatchPairTree :: for_pattern ( subplace, subpat, cx, & mut subpairs, extra_data) ;
227+ }
233228 } else {
234229 // If the array length couldn't be determined, ignore the
235230 // subpatterns and delayed-assert that compilation will fail.
@@ -245,15 +240,11 @@ impl<'tcx> MatchPairTree<'tcx> {
245240 None
246241 }
247242 PatKind :: Slice { ref prefix, ref slice, ref suffix } => {
248- cx. prefix_slice_suffix (
249- & mut subpairs,
250- extra_data,
251- & place_builder,
252- None ,
253- prefix,
254- slice,
255- suffix,
256- ) ;
243+ for ( subplace, subpat) in
244+ prefix_slice_suffix ( & place_builder, None , prefix, slice, suffix)
245+ {
246+ MatchPairTree :: for_pattern ( subplace, subpat, cx, & mut subpairs, extra_data) ;
247+ }
257248
258249 if prefix. is_empty ( ) && slice. is_some ( ) && suffix. is_empty ( ) {
259250 // This pattern is shaped like `[..]`. It can match a slice
0 commit comments