@@ -12,77 +12,58 @@ use crate::builder::matches::{
1212 FlatPat , MatchPairTree , PatConstKind , PatternExtraData , SliceLenOp , TestableCase ,
1313} ;
1414
15- impl < ' a , ' tcx > Builder < ' a , ' tcx > {
16- /// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in
17- /// `subpatterns`, representing the fields of a [`PatKind::Variant`] or
18- /// [`PatKind::Leaf`].
19- ///
20- /// Used internally by [`MatchPairTree::for_pattern`].
21- fn field_match_pairs (
22- & mut self ,
23- match_pairs : & mut Vec < MatchPairTree < ' tcx > > ,
24- extra_data : & mut PatternExtraData < ' tcx > ,
25- place : PlaceBuilder < ' tcx > ,
26- subpatterns : & [ FieldPat < ' tcx > ] ,
27- ) {
28- for fieldpat in subpatterns {
29- let place = place. clone_project ( PlaceElem :: Field ( fieldpat. field , fieldpat. pattern . ty ) ) ;
30- MatchPairTree :: for_pattern ( place, & fieldpat. pattern , self , match_pairs, extra_data) ;
31- }
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) ) ;
3244 }
3345
34- /// Builds [`MatchPairTree`] subtrees for the prefix/middle/suffix parts of an
35- /// array pattern or slice pattern, and adds those trees to `match_pairs`.
36- ///
37- /// Used internally by [`MatchPairTree::for_pattern`].
38- fn prefix_slice_suffix (
39- & mut self ,
40- match_pairs : & mut Vec < MatchPairTree < ' tcx > > ,
41- extra_data : & mut PatternExtraData < ' tcx > ,
42- place : & PlaceBuilder < ' tcx > ,
43- array_len : Option < u64 > ,
44- prefix : & [ Pat < ' tcx > ] ,
45- opt_slice : & Option < Box < Pat < ' tcx > > > ,
46- suffix : & [ Pat < ' tcx > ] ,
47- ) {
48- let prefix_len = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
49- let suffix_len = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
50-
51- // For slice patterns with a `..` followed by 0 or more suffix subpatterns,
52- // the actual slice index of those subpatterns isn't statically known, so
53- // we have to index them relative to the end of the slice.
54- //
55- // For array patterns, all subpatterns are indexed relative to the start.
56- let ( min_length, is_array) = match array_len {
57- Some ( len) => ( len, true ) ,
58- None => ( prefix_len + suffix_len, false ) ,
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,
5951 } ;
52+ let subplace = place. clone_project ( elem) ;
53+ output_pairs. push ( ( subplace, slice_subpat) ) ;
54+ }
6055
61- for ( offset, subpattern) in ( 0u64 ..) . zip ( prefix) {
62- let elem = ProjectionElem :: ConstantIndex { offset, min_length, from_end : false } ;
63- let place = place. clone_project ( elem) ;
64- MatchPairTree :: for_pattern ( place, subpattern, self , match_pairs, extra_data)
65- }
66-
67- if let Some ( subslice_pat) = opt_slice {
68- let subslice = place. clone_project ( PlaceElem :: Subslice {
69- from : prefix_len,
70- to : if is_array { min_length - suffix_len } else { suffix_len } ,
71- from_end : !is_array,
72- } ) ;
73- MatchPairTree :: for_pattern ( subslice, subslice_pat, self , match_pairs, extra_data) ;
74- }
75-
76- for ( end_offset, subpattern) in ( 1u64 ..) . zip ( suffix. iter ( ) . rev ( ) ) {
77- let elem = ProjectionElem :: ConstantIndex {
78- offset : if is_array { min_length - end_offset } else { end_offset } ,
79- min_length,
80- from_end : !is_array,
81- } ;
82- let place = place. clone_project ( elem) ;
83- MatchPairTree :: for_pattern ( place, subpattern, self , match_pairs, extra_data)
84- }
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) ) ;
8564 }
65+
66+ output_pairs
8667}
8768
8869impl < ' tcx > MatchPairTree < ' tcx > {
@@ -239,15 +220,11 @@ impl<'tcx> MatchPairTree<'tcx> {
239220 _ => None ,
240221 } ;
241222 if let Some ( array_len) = array_len {
242- cx. prefix_slice_suffix (
243- & mut subpairs,
244- extra_data,
245- & place_builder,
246- Some ( array_len) ,
247- prefix,
248- slice,
249- suffix,
250- ) ;
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+ }
251228 } else {
252229 // If the array length couldn't be determined, ignore the
253230 // subpatterns and delayed-assert that compilation will fail.
@@ -263,15 +240,11 @@ impl<'tcx> MatchPairTree<'tcx> {
263240 None
264241 }
265242 PatKind :: Slice { ref prefix, ref slice, ref suffix } => {
266- cx. prefix_slice_suffix (
267- & mut subpairs,
268- extra_data,
269- & place_builder,
270- None ,
271- prefix,
272- slice,
273- suffix,
274- ) ;
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+ }
275248
276249 if prefix. is_empty ( ) && slice. is_some ( ) && suffix. is_empty ( ) {
277250 // This pattern is shaped like `[..]`. It can match a slice
@@ -294,7 +267,10 @@ impl<'tcx> MatchPairTree<'tcx> {
294267
295268 PatKind :: Variant { adt_def, variant_index, args : _, ref subpatterns } => {
296269 let downcast_place = place_builder. downcast ( adt_def, variant_index) ; // `(x as Variant)`
297- cx. field_match_pairs ( & mut subpairs, extra_data, downcast_place, subpatterns) ;
270+ for & FieldPat { field, pattern : ref subpat } in subpatterns {
271+ let subplace = downcast_place. clone_project ( PlaceElem :: Field ( field, subpat. ty ) ) ;
272+ MatchPairTree :: for_pattern ( subplace, subpat, cx, & mut subpairs, extra_data) ;
273+ }
298274
299275 // We treat non-exhaustive enums the same independent of the crate they are
300276 // defined in, to avoid differences in the operational semantics between crates.
@@ -308,7 +284,10 @@ impl<'tcx> MatchPairTree<'tcx> {
308284 }
309285
310286 PatKind :: Leaf { ref subpatterns } => {
311- cx. field_match_pairs ( & mut subpairs, extra_data, place_builder, subpatterns) ;
287+ for & FieldPat { field, pattern : ref subpat } in subpatterns {
288+ let subplace = place_builder. clone_project ( PlaceElem :: Field ( field, subpat. ty ) ) ;
289+ MatchPairTree :: for_pattern ( subplace, subpat, cx, & mut subpairs, extra_data) ;
290+ }
312291 None
313292 }
314293
0 commit comments