@@ -12,76 +12,66 @@ 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+ /// Visits each of the immediate subpatterns of a tuple, struct, or enum-variant pattern,
16+ /// along with a suitably-projected [`PlaceBuilder`] for each.
17+ fn for_each_field_subpat < ' tcx > (
18+ place : & PlaceBuilder < ' tcx > ,
19+ subpatterns : & [ FieldPat < ' tcx > ] ,
20+ mut callback_fn : impl FnMut ( PlaceBuilder < ' tcx > , & Pat < ' tcx > ) ,
21+ ) {
22+ for fieldpat in subpatterns {
23+ let subplace = place. clone_project ( PlaceElem :: Field ( fieldpat. field , fieldpat. pattern . ty ) ) ;
24+ callback_fn ( subplace, & fieldpat. pattern ) ;
3225 }
26+ }
3327
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 ) ,
59- } ;
60-
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- }
28+ /// Visits each of the immediate subpatterns of an array pattern or slice pattern,
29+ /// along with a suitably-projected [`PlaceBuilder`] for each.
30+ fn for_each_subpat_of_array_or_slice < ' tcx > (
31+ place : & PlaceBuilder < ' tcx > ,
32+ array_len : Option < u64 > , // Some for array patterns, None for slice patterns
33+ prefix : & [ Pat < ' tcx > ] ,
34+ opt_middle : & Option < Box < Pat < ' tcx > > > ,
35+ suffix : & [ Pat < ' tcx > ] ,
36+ mut callback_fn : impl FnMut ( PlaceBuilder < ' tcx > , & Pat < ' tcx > ) ,
37+ ) {
38+ let prefix_len = u64:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
39+ let suffix_len = u64:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
40+
41+ // For slice patterns with a `..` followed by 0 or more suffix subpatterns,
42+ // the actual slice index of those subpatterns isn't statically known, so
43+ // we have to index them relative to the end of the slice.
44+ //
45+ // For array patterns, all subpatterns are indexed relative to the start.
46+ let ( min_length, is_array) = match array_len {
47+ Some ( len) => ( len, true ) ,
48+ None => ( prefix_len + suffix_len, false ) ,
49+ } ;
50+
51+ for ( offset, prefix_subpat) in ( 0u64 ..) . zip ( prefix) {
52+ let elem = ProjectionElem :: ConstantIndex { offset, min_length, from_end : false } ;
53+ let subplace = place. clone_project ( elem) ;
54+ callback_fn ( subplace, prefix_subpat) ;
55+ }
6656
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- }
57+ if let Some ( middle_subpat) = opt_middle {
58+ let elem = PlaceElem :: Subslice {
59+ from : prefix_len,
60+ to : if is_array { min_length - suffix_len } else { suffix_len } ,
61+ from_end : !is_array,
62+ } ;
63+ let subplace = place. clone_project ( elem) ;
64+ callback_fn ( subplace, middle_subpat) ;
65+ }
7566
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- }
67+ for ( end_offset, suffix_subpat) in ( 1u64 ..) . zip ( suffix. iter ( ) . rev ( ) ) {
68+ let elem = ProjectionElem :: ConstantIndex {
69+ offset : if is_array { min_length - end_offset } else { end_offset } ,
70+ min_length,
71+ from_end : !is_array,
72+ } ;
73+ let subplace = place. clone_project ( elem) ;
74+ callback_fn ( subplace, suffix_subpat) ;
8575 }
8676}
8777
@@ -238,14 +228,21 @@ impl<'tcx> MatchPairTree<'tcx> {
238228 _ => None ,
239229 } ;
240230 if let Some ( array_len) = array_len {
241- cx. prefix_slice_suffix (
242- & mut subpairs,
243- extra_data,
231+ for_each_subpat_of_array_or_slice (
244232 & place_builder,
245233 Some ( array_len) ,
246234 prefix,
247235 slice,
248236 suffix,
237+ |subplace, subpat| {
238+ MatchPairTree :: for_pattern (
239+ subplace,
240+ subpat,
241+ cx,
242+ & mut subpairs,
243+ extra_data,
244+ ) ;
245+ } ,
249246 ) ;
250247 } else {
251248 // If the array length couldn't be determined, ignore the
@@ -262,14 +259,15 @@ impl<'tcx> MatchPairTree<'tcx> {
262259 None
263260 }
264261 PatKind :: Slice { ref prefix, ref slice, ref suffix } => {
265- cx. prefix_slice_suffix (
266- & mut subpairs,
267- extra_data,
262+ for_each_subpat_of_array_or_slice (
268263 & place_builder,
269264 None ,
270265 prefix,
271266 slice,
272267 suffix,
268+ |subplace, subpat| {
269+ MatchPairTree :: for_pattern ( subplace, subpat, cx, & mut subpairs, extra_data) ;
270+ } ,
273271 ) ;
274272
275273 if prefix. is_empty ( ) && slice. is_some ( ) && suffix. is_empty ( ) {
@@ -293,7 +291,9 @@ impl<'tcx> MatchPairTree<'tcx> {
293291
294292 PatKind :: Variant { adt_def, variant_index, args : _, ref subpatterns } => {
295293 let downcast_place = place_builder. downcast ( adt_def, variant_index) ; // `(x as Variant)`
296- cx. field_match_pairs ( & mut subpairs, extra_data, downcast_place, subpatterns) ;
294+ for_each_field_subpat ( & downcast_place, subpatterns, |subplace, subpat| {
295+ MatchPairTree :: for_pattern ( subplace, subpat, cx, & mut subpairs, extra_data) ;
296+ } ) ;
297297
298298 // We treat non-exhaustive enums the same independent of the crate they are
299299 // defined in, to avoid differences in the operational semantics between crates.
@@ -307,7 +307,9 @@ impl<'tcx> MatchPairTree<'tcx> {
307307 }
308308
309309 PatKind :: Leaf { ref subpatterns } => {
310- cx. field_match_pairs ( & mut subpairs, extra_data, place_builder, subpatterns) ;
310+ for_each_field_subpat ( & place_builder, subpatterns, |subplace, subpat| {
311+ MatchPairTree :: for_pattern ( subplace, subpat, cx, & mut subpairs, extra_data) ;
312+ } ) ;
311313 None
312314 }
313315
0 commit comments