@@ -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,35 @@ 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+ impl < ' tcx > PatternExtraData < ' tcx > {
942+ fn is_empty ( & self ) -> bool {
943+ self . bindings . is_empty ( ) && self . ascriptions . is_empty ( )
944+ }
945+ }
946+
947+ /// A pattern in a form suitable for generating code.
948+ #[ derive( Debug , Clone ) ]
949+ struct FlatPat < ' pat , ' tcx > {
933950 /// To match the pattern, all of these must be satisfied...
934951 // Invariant: all the `MatchPair`s are recursively simplified.
935952 // Invariant: or-patterns must be sorted to the end.
936953 match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
937954
938- /// ...these bindings established...
939- bindings : Vec < Binding < ' tcx > > ,
940-
941- /// ...and these types asserted.
942- ascriptions : Vec < Ascription < ' tcx > > ,
955+ extra_data : PatternExtraData < ' tcx > ,
943956}
944957
945958impl < ' tcx , ' pat > FlatPat < ' pat , ' tcx > {
@@ -948,43 +961,38 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
948961 pattern : & ' pat Pat < ' tcx > ,
949962 cx : & mut Builder < ' _ , ' tcx > ,
950963 ) -> 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 }
964+ let mut flat_pat = FlatPat {
965+ match_pairs : vec ! [ MatchPair :: new( place, pattern, cx) ] ,
966+ extra_data : PatternExtraData {
967+ span : pattern. span ,
968+ bindings : Vec :: new ( ) ,
969+ ascriptions : Vec :: new ( ) ,
970+ } ,
971+ } ;
972+ cx. simplify_match_pairs ( & mut flat_pat. match_pairs , & mut flat_pat. extra_data ) ;
973+ flat_pat
958974 }
959975}
960976
961977#[ derive( Debug ) ]
962978struct 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...
979+ /// For the candidate to match, all of these must be satisfied...
970980 // Invariant: all the `MatchPair`s are recursively simplified.
971981 // Invariant: or-patterns must be sorted at the end.
972982 match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
973983
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-
982984 /// ...and if this is non-empty, one of these subcandidates also has to match...
983985 subcandidates : Vec < Candidate < ' pat , ' tcx > > ,
984986
985- /// ...and the guard must be evaluated; if it's `false` then branch to `otherwise_block`.
987+ /// ...and the guard must be evaluated if there is one.
988+ has_guard : bool ,
989+
990+ /// If the guard is `false` then branch to `otherwise_block`.
986991 otherwise_block : Option < BasicBlock > ,
987992
993+ /// If the candidate matches, bindings and ascriptions must be established.
994+ extra_data : PatternExtraData < ' tcx > ,
995+
988996 /// The block before the `bindings` have been established.
989997 pre_binding_block : Option < BasicBlock > ,
990998 /// The pre-binding block of the next candidate.
@@ -1003,10 +1011,8 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
10031011
10041012 fn from_flat_pat ( flat_pat : FlatPat < ' pat , ' tcx > , has_guard : bool ) -> Self {
10051013 Candidate {
1006- span : flat_pat. span ,
10071014 match_pairs : flat_pat. match_pairs ,
1008- bindings : flat_pat. bindings ,
1009- ascriptions : flat_pat. ascriptions ,
1015+ extra_data : flat_pat. extra_data ,
10101016 has_guard,
10111017 subcandidates : Vec :: new ( ) ,
10121018 otherwise_block : None ,
@@ -1518,9 +1524,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15181524 self . merge_trivial_subcandidates ( subcandidate, source_info) ;
15191525
15201526 // FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
1521- can_merge &= subcandidate. subcandidates . is_empty ( )
1522- && subcandidate. bindings . is_empty ( )
1523- && subcandidate. ascriptions . is_empty ( ) ;
1527+ can_merge &=
1528+ subcandidate. subcandidates . is_empty ( ) && subcandidate. extra_data . is_empty ( ) ;
15241529 }
15251530
15261531 if can_merge {
@@ -1943,7 +1948,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19431948 fn bind_and_guard_matched_candidate < ' pat > (
19441949 & mut self ,
19451950 candidate : Candidate < ' pat , ' tcx > ,
1946- parent_bindings : & [ ( Vec < Binding < ' tcx > > , Vec < Ascription < ' tcx > > ) ] ,
1951+ parent_data : & [ PatternExtraData < ' tcx > ] ,
19471952 fake_borrows : & [ ( Place < ' tcx > , Local ) ] ,
19481953 scrutinee_span : Span ,
19491954 arm_match_scope : Option < ( & Arm < ' tcx > , region:: Scope ) > ,
@@ -1954,7 +1959,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19541959
19551960 debug_assert ! ( candidate. match_pairs. is_empty( ) ) ;
19561961
1957- let candidate_source_info = self . source_info ( candidate. span ) ;
1962+ let candidate_source_info = self . source_info ( candidate. extra_data . span ) ;
19581963
19591964 let mut block = candidate. pre_binding_block . unwrap ( ) ;
19601965
@@ -1971,11 +1976,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19711976
19721977 self . ascribe_types (
19731978 block,
1974- parent_bindings
1979+ parent_data
19751980 . iter ( )
1976- . flat_map ( |( _ , ascriptions ) | ascriptions)
1981+ . flat_map ( |d| & d . ascriptions )
19771982 . cloned ( )
1978- . chain ( candidate. ascriptions ) ,
1983+ . chain ( candidate. extra_data . ascriptions ) ,
19791984 ) ;
19801985
19811986 // rust-lang/rust#27282: The `autoref` business deserves some
@@ -2063,10 +2068,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20632068 && let Some ( guard) = arm. guard
20642069 {
20652070 let tcx = self . tcx ;
2066- let bindings = parent_bindings
2067- . iter ( )
2068- . flat_map ( |( bindings, _) | bindings)
2069- . chain ( & candidate. bindings ) ;
2071+ let bindings =
2072+ parent_data. iter ( ) . flat_map ( |d| & d. bindings ) . chain ( & candidate. extra_data . bindings ) ;
20702073
20712074 self . bind_matched_candidate_for_guard ( block, schedule_drops, bindings. clone ( ) ) ;
20722075 let guard_frame = GuardFrame {
@@ -2144,10 +2147,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21442147 // ```
21452148 //
21462149 // and that is clearly not correct.
2147- let by_value_bindings = parent_bindings
2150+ let by_value_bindings = parent_data
21482151 . iter ( )
2149- . flat_map ( |( bindings , _ ) | bindings)
2150- . chain ( & candidate. bindings )
2152+ . flat_map ( |d| & d . bindings )
2153+ . chain ( & candidate. extra_data . bindings )
21512154 . filter ( |binding| matches ! ( binding. binding_mode, BindingMode :: ByValue ) ) ;
21522155 // Read all of the by reference bindings to ensure that the
21532156 // place they refer to can't be modified by the guard.
@@ -2172,10 +2175,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21722175 self . bind_matched_candidate_for_arm_body (
21732176 block,
21742177 schedule_drops,
2175- parent_bindings
2176- . iter ( )
2177- . flat_map ( |( bindings, _) | bindings)
2178- . chain ( & candidate. bindings ) ,
2178+ parent_data. iter ( ) . flat_map ( |d| & d. bindings ) . chain ( & candidate. extra_data . bindings ) ,
21792179 storages_alive,
21802180 ) ;
21812181 block
0 commit comments