@@ -506,13 +506,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
506506 traverse_candidate (
507507 candidate,
508508 & mut Vec :: new ( ) ,
509- & mut |leaf_candidate, parent_bindings | {
509+ & mut |leaf_candidate, parent_data | {
510510 if let Some ( arm) = arm {
511511 self . clear_top_scope ( arm. scope ) ;
512512 }
513513 let binding_end = self . bind_and_guard_matched_candidate (
514514 leaf_candidate,
515- parent_bindings ,
515+ parent_data ,
516516 fake_borrow_temps,
517517 scrutinee_span,
518518 arm_match_scope,
@@ -524,12 +524,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
524524 }
525525 self . cfg . goto ( binding_end, outer_source_info, target_block) ;
526526 } ,
527- |inner_candidate, parent_bindings | {
528- parent_bindings . push ( ( inner_candidate. bindings , inner_candidate . ascriptions ) ) ;
527+ |inner_candidate, parent_data | {
528+ parent_data . push ( inner_candidate. extra_data ) ;
529529 inner_candidate. subcandidates . into_iter ( )
530530 } ,
531- |parent_bindings | {
532- parent_bindings . pop ( ) ;
531+ |parent_data | {
532+ parent_data . pop ( ) ;
533533 } ,
534534 ) ;
535535
@@ -651,7 +651,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
651651 if set_match_place {
652652 let mut next = Some ( & candidate) ;
653653 while let Some ( candidate_ref) = next. take ( ) {
654- for binding in & candidate_ref. bindings {
654+ for binding in & candidate_ref. extra_data . bindings {
655655 let local = self . var_local_id ( binding. var_id , OutsideGuard ) ;
656656 // `try_to_place` may fail if it is unable to resolve the given
657657 // `PlaceBuilder` inside a closure. In this case, we don't want to include
@@ -924,22 +924,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
924924 }
925925}
926926
927- /// A pattern in a form suitable for generating code.
927+ /// Data extracted from a pattern that doesn't affect which branch is taken. Collected during
928+ /// pattern simplification and not mutated later.
928929#[ derive( Debug , Clone ) ]
929- struct FlatPat < ' pat , ' tcx > {
930+ struct PatternExtraData < ' tcx > {
930931 /// [`Span`] of the original pattern.
931932 span : Span ,
932933
934+ /// Bindings that must be established.
935+ bindings : Vec < Binding < ' tcx > > ,
936+
937+ /// Types that must be asserted.
938+ ascriptions : Vec < Ascription < ' tcx > > ,
939+ }
940+
941+ /// A pattern in a form suitable for generating code.
942+ #[ derive( Debug , Clone ) ]
943+ struct FlatPat < ' pat , ' tcx > {
933944 /// To match the pattern, all of these must be satisfied...
934945 // Invariant: all the `MatchPair`s are recursively simplified.
935946 // Invariant: or-patterns must be sorted to the end.
936947 match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
937948
938- /// ...these bindings established...
939- bindings : Vec < Binding < ' tcx > > ,
940-
941- /// ...and these types asserted.
942- ascriptions : Vec < Ascription < ' tcx > > ,
949+ extra_data : PatternExtraData < ' tcx > ,
943950}
944951
945952impl < ' tcx , ' pat > FlatPat < ' pat , ' tcx > {
@@ -948,43 +955,38 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
948955 pattern : & ' pat Pat < ' tcx > ,
949956 cx : & mut Builder < ' _ , ' tcx > ,
950957 ) -> Self {
951- let mut match_pairs = vec ! [ MatchPair :: new( place, pattern, cx) ] ;
952- let mut bindings = Vec :: new ( ) ;
953- let mut ascriptions = Vec :: new ( ) ;
954-
955- cx. simplify_match_pairs ( & mut match_pairs, & mut bindings, & mut ascriptions) ;
956-
957- FlatPat { span : pattern. span , match_pairs, bindings, ascriptions }
958+ let mut flat_pat = FlatPat {
959+ match_pairs : vec ! [ MatchPair :: new( place, pattern, cx) ] ,
960+ extra_data : PatternExtraData {
961+ span : pattern. span ,
962+ bindings : Vec :: new ( ) ,
963+ ascriptions : Vec :: new ( ) ,
964+ } ,
965+ } ;
966+ cx. simplify_match_pairs ( & mut flat_pat. match_pairs , & mut flat_pat. extra_data ) ;
967+ flat_pat
958968 }
959969}
960970
961971#[ derive( Debug ) ]
962972struct Candidate < ' pat , ' tcx > {
963- /// [`Span`] of the original pattern that gave rise to this candidate.
964- span : Span ,
965-
966- /// Whether this `Candidate` has a guard.
967- has_guard : bool ,
968-
969- /// All of these must be satisfied...
973+ /// For the candidate to match, &ll of these must be satisfied...
970974 // Invariant: all the `MatchPair`s are recursively simplified.
971975 // Invariant: or-patterns must be sorted at the end.
972976 match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
973977
974- /// ...these bindings established...
975- // Invariant: not mutated after candidate creation.
976- bindings : Vec < Binding < ' tcx > > ,
977-
978- /// ...and these types asserted...
979- // Invariant: not mutated after candidate creation.
980- ascriptions : Vec < Ascription < ' tcx > > ,
981-
982978 /// ...and if this is non-empty, one of these subcandidates also has to match...
983979 subcandidates : Vec < Candidate < ' pat , ' tcx > > ,
984980
985- /// ...and the guard must be evaluated; if it's `false` then branch to `otherwise_block`.
981+ /// ...and the guard must be evaluated if there is one.
982+ has_guard : bool ,
983+
984+ /// If the guard is `false` then branch to `otherwise_block`.
986985 otherwise_block : Option < BasicBlock > ,
987986
987+ /// If the candidate matches, bindings and ascriptions must be established.
988+ extra_data : PatternExtraData < ' tcx > ,
989+
988990 /// The block before the `bindings` have been established.
989991 pre_binding_block : Option < BasicBlock > ,
990992 /// The pre-binding block of the next candidate.
@@ -1003,10 +1005,8 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
10031005
10041006 fn from_flat_pat ( flat_pat : FlatPat < ' pat , ' tcx > , has_guard : bool ) -> Self {
10051007 Candidate {
1006- span : flat_pat. span ,
10071008 match_pairs : flat_pat. match_pairs ,
1008- bindings : flat_pat. bindings ,
1009- ascriptions : flat_pat. ascriptions ,
1009+ extra_data : flat_pat. extra_data ,
10101010 has_guard,
10111011 subcandidates : Vec :: new ( ) ,
10121012 otherwise_block : None ,
@@ -1519,8 +1519,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15191519
15201520 // FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
15211521 can_merge &= subcandidate. subcandidates . is_empty ( )
1522- && subcandidate. bindings . is_empty ( )
1523- && subcandidate. ascriptions . is_empty ( ) ;
1522+ && subcandidate. extra_data . bindings . is_empty ( )
1523+ && subcandidate. extra_data . ascriptions . is_empty ( ) ;
15241524 }
15251525
15261526 if can_merge {
@@ -1943,7 +1943,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19431943 fn bind_and_guard_matched_candidate < ' pat > (
19441944 & mut self ,
19451945 candidate : Candidate < ' pat , ' tcx > ,
1946- parent_bindings : & [ ( Vec < Binding < ' tcx > > , Vec < Ascription < ' tcx > > ) ] ,
1946+ parent_data : & [ PatternExtraData < ' tcx > ] ,
19471947 fake_borrows : & [ ( Place < ' tcx > , Local ) ] ,
19481948 scrutinee_span : Span ,
19491949 arm_match_scope : Option < ( & Arm < ' tcx > , region:: Scope ) > ,
@@ -1954,7 +1954,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19541954
19551955 debug_assert ! ( candidate. match_pairs. is_empty( ) ) ;
19561956
1957- let candidate_source_info = self . source_info ( candidate. span ) ;
1957+ let candidate_source_info = self . source_info ( candidate. extra_data . span ) ;
19581958
19591959 let mut block = candidate. pre_binding_block . unwrap ( ) ;
19601960
@@ -1971,11 +1971,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19711971
19721972 self . ascribe_types (
19731973 block,
1974- parent_bindings
1974+ parent_data
19751975 . iter ( )
1976- . flat_map ( |( _ , ascriptions ) | ascriptions)
1976+ . flat_map ( |d| & d . ascriptions )
19771977 . cloned ( )
1978- . chain ( candidate. ascriptions ) ,
1978+ . chain ( candidate. extra_data . ascriptions ) ,
19791979 ) ;
19801980
19811981 // rust-lang/rust#27282: The `autoref` business deserves some
@@ -2063,10 +2063,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20632063 && let Some ( guard) = arm. guard
20642064 {
20652065 let tcx = self . tcx ;
2066- let bindings = parent_bindings
2067- . iter ( )
2068- . flat_map ( |( bindings, _) | bindings)
2069- . chain ( & candidate. bindings ) ;
2066+ let bindings =
2067+ parent_data. iter ( ) . flat_map ( |d| & d. bindings ) . chain ( & candidate. extra_data . bindings ) ;
20702068
20712069 self . bind_matched_candidate_for_guard ( block, schedule_drops, bindings. clone ( ) ) ;
20722070 let guard_frame = GuardFrame {
@@ -2144,10 +2142,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21442142 // ```
21452143 //
21462144 // and that is clearly not correct.
2147- let by_value_bindings = parent_bindings
2145+ let by_value_bindings = parent_data
21482146 . iter ( )
2149- . flat_map ( |( bindings , _ ) | bindings)
2150- . chain ( & candidate. bindings )
2147+ . flat_map ( |d| & d . bindings )
2148+ . chain ( & candidate. extra_data . bindings )
21512149 . filter ( |binding| matches ! ( binding. binding_mode, BindingMode :: ByValue ) ) ;
21522150 // Read all of the by reference bindings to ensure that the
21532151 // place they refer to can't be modified by the guard.
@@ -2172,10 +2170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21722170 self . bind_matched_candidate_for_arm_body (
21732171 block,
21742172 schedule_drops,
2175- parent_bindings
2176- . iter ( )
2177- . flat_map ( |( bindings, _) | bindings)
2178- . chain ( & candidate. bindings ) ,
2173+ parent_data. iter ( ) . flat_map ( |d| & d. bindings ) . chain ( & candidate. extra_data . bindings ) ,
21792174 storages_alive,
21802175 ) ;
21812176 block
0 commit comments