@@ -506,13 +506,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
506
506
traverse_candidate (
507
507
candidate,
508
508
& mut Vec :: new ( ) ,
509
- & mut |leaf_candidate, parent_bindings | {
509
+ & mut |leaf_candidate, parent_data | {
510
510
if let Some ( arm) = arm {
511
511
self . clear_top_scope ( arm. scope ) ;
512
512
}
513
513
let binding_end = self . bind_and_guard_matched_candidate (
514
514
leaf_candidate,
515
- parent_bindings ,
515
+ parent_data ,
516
516
fake_borrow_temps,
517
517
scrutinee_span,
518
518
arm_match_scope,
@@ -524,12 +524,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
524
524
}
525
525
self . cfg . goto ( binding_end, outer_source_info, target_block) ;
526
526
} ,
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 ) ;
529
529
inner_candidate. subcandidates . into_iter ( )
530
530
} ,
531
- |parent_bindings | {
532
- parent_bindings . pop ( ) ;
531
+ |parent_data | {
532
+ parent_data . pop ( ) ;
533
533
} ,
534
534
) ;
535
535
@@ -651,7 +651,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
651
651
if set_match_place {
652
652
let mut next = Some ( & candidate) ;
653
653
while let Some ( candidate_ref) = next. take ( ) {
654
- for binding in & candidate_ref. bindings {
654
+ for binding in & candidate_ref. extra_data . bindings {
655
655
let local = self . var_local_id ( binding. var_id , OutsideGuard ) ;
656
656
// `try_to_place` may fail if it is unable to resolve the given
657
657
// `PlaceBuilder` inside a closure. In this case, we don't want to include
@@ -924,22 +924,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
924
924
}
925
925
}
926
926
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.
928
929
#[ derive( Debug , Clone ) ]
929
- struct FlatPat < ' pat , ' tcx > {
930
+ struct PatternExtraData < ' tcx > {
930
931
/// [`Span`] of the original pattern.
931
932
span : Span ,
932
933
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 > {
933
944
/// To match the pattern, all of these must be satisfied...
934
945
// Invariant: all the `MatchPair`s are recursively simplified.
935
946
// Invariant: or-patterns must be sorted to the end.
936
947
match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
937
948
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 > ,
943
950
}
944
951
945
952
impl < ' tcx , ' pat > FlatPat < ' pat , ' tcx > {
@@ -948,43 +955,38 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
948
955
pattern : & ' pat Pat < ' tcx > ,
949
956
cx : & mut Builder < ' _ , ' tcx > ,
950
957
) -> 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
958
968
}
959
969
}
960
970
961
971
#[ derive( Debug ) ]
962
972
struct 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...
970
974
// Invariant: all the `MatchPair`s are recursively simplified.
971
975
// Invariant: or-patterns must be sorted at the end.
972
976
match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
973
977
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
-
982
978
/// ...and if this is non-empty, one of these subcandidates also has to match...
983
979
subcandidates : Vec < Candidate < ' pat , ' tcx > > ,
984
980
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`.
986
985
otherwise_block : Option < BasicBlock > ,
987
986
987
+ /// If the candidate matches, bindings and ascriptions must be established.
988
+ extra_data : PatternExtraData < ' tcx > ,
989
+
988
990
/// The block before the `bindings` have been established.
989
991
pre_binding_block : Option < BasicBlock > ,
990
992
/// The pre-binding block of the next candidate.
@@ -1003,10 +1005,8 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
1003
1005
1004
1006
fn from_flat_pat ( flat_pat : FlatPat < ' pat , ' tcx > , has_guard : bool ) -> Self {
1005
1007
Candidate {
1006
- span : flat_pat. span ,
1007
1008
match_pairs : flat_pat. match_pairs ,
1008
- bindings : flat_pat. bindings ,
1009
- ascriptions : flat_pat. ascriptions ,
1009
+ extra_data : flat_pat. extra_data ,
1010
1010
has_guard,
1011
1011
subcandidates : Vec :: new ( ) ,
1012
1012
otherwise_block : None ,
@@ -1519,8 +1519,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1519
1519
1520
1520
// FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
1521
1521
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 ( ) ;
1524
1524
}
1525
1525
1526
1526
if can_merge {
@@ -1943,7 +1943,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1943
1943
fn bind_and_guard_matched_candidate < ' pat > (
1944
1944
& mut self ,
1945
1945
candidate : Candidate < ' pat , ' tcx > ,
1946
- parent_bindings : & [ ( Vec < Binding < ' tcx > > , Vec < Ascription < ' tcx > > ) ] ,
1946
+ parent_data : & [ PatternExtraData < ' tcx > ] ,
1947
1947
fake_borrows : & [ ( Place < ' tcx > , Local ) ] ,
1948
1948
scrutinee_span : Span ,
1949
1949
arm_match_scope : Option < ( & Arm < ' tcx > , region:: Scope ) > ,
@@ -1954,7 +1954,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1954
1954
1955
1955
debug_assert ! ( candidate. match_pairs. is_empty( ) ) ;
1956
1956
1957
- let candidate_source_info = self . source_info ( candidate. span ) ;
1957
+ let candidate_source_info = self . source_info ( candidate. extra_data . span ) ;
1958
1958
1959
1959
let mut block = candidate. pre_binding_block . unwrap ( ) ;
1960
1960
@@ -1971,11 +1971,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1971
1971
1972
1972
self . ascribe_types (
1973
1973
block,
1974
- parent_bindings
1974
+ parent_data
1975
1975
. iter ( )
1976
- . flat_map ( |( _ , ascriptions ) | ascriptions)
1976
+ . flat_map ( |d| & d . ascriptions )
1977
1977
. cloned ( )
1978
- . chain ( candidate. ascriptions ) ,
1978
+ . chain ( candidate. extra_data . ascriptions ) ,
1979
1979
) ;
1980
1980
1981
1981
// rust-lang/rust#27282: The `autoref` business deserves some
@@ -2063,10 +2063,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2063
2063
&& let Some ( guard) = arm. guard
2064
2064
{
2065
2065
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 ) ;
2070
2068
2071
2069
self . bind_matched_candidate_for_guard ( block, schedule_drops, bindings. clone ( ) ) ;
2072
2070
let guard_frame = GuardFrame {
@@ -2144,10 +2142,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2144
2142
// ```
2145
2143
//
2146
2144
// and that is clearly not correct.
2147
- let by_value_bindings = parent_bindings
2145
+ let by_value_bindings = parent_data
2148
2146
. iter ( )
2149
- . flat_map ( |( bindings , _ ) | bindings)
2150
- . chain ( & candidate. bindings )
2147
+ . flat_map ( |d| & d . bindings )
2148
+ . chain ( & candidate. extra_data . bindings )
2151
2149
. filter ( |binding| matches ! ( binding. binding_mode, BindingMode :: ByValue ) ) ;
2152
2150
// Read all of the by reference bindings to ensure that the
2153
2151
// place they refer to can't be modified by the guard.
@@ -2172,10 +2170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2172
2170
self . bind_matched_candidate_for_arm_body (
2173
2171
block,
2174
2172
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 ) ,
2179
2174
storages_alive,
2180
2175
) ;
2181
2176
block
0 commit comments