@@ -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,35 @@ 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
+ 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 > {
933
950
/// To match the pattern, all of these must be satisfied...
934
951
// Invariant: all the `MatchPair`s are recursively simplified.
935
952
// Invariant: or-patterns must be sorted to the end.
936
953
match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
937
954
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 > ,
943
956
}
944
957
945
958
impl < ' tcx , ' pat > FlatPat < ' pat , ' tcx > {
@@ -948,43 +961,38 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
948
961
pattern : & ' pat Pat < ' tcx > ,
949
962
cx : & mut Builder < ' _ , ' tcx > ,
950
963
) -> 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
958
974
}
959
975
}
960
976
961
977
#[ derive( Debug ) ]
962
978
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...
979
+ /// For the candidate to match, all of these must be satisfied...
970
980
// Invariant: all the `MatchPair`s are recursively simplified.
971
981
// Invariant: or-patterns must be sorted at the end.
972
982
match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
973
983
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
984
/// ...and if this is non-empty, one of these subcandidates also has to match...
983
985
subcandidates : Vec < Candidate < ' pat , ' tcx > > ,
984
986
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`.
986
991
otherwise_block : Option < BasicBlock > ,
987
992
993
+ /// If the candidate matches, bindings and ascriptions must be established.
994
+ extra_data : PatternExtraData < ' tcx > ,
995
+
988
996
/// The block before the `bindings` have been established.
989
997
pre_binding_block : Option < BasicBlock > ,
990
998
/// The pre-binding block of the next candidate.
@@ -1003,10 +1011,8 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
1003
1011
1004
1012
fn from_flat_pat ( flat_pat : FlatPat < ' pat , ' tcx > , has_guard : bool ) -> Self {
1005
1013
Candidate {
1006
- span : flat_pat. span ,
1007
1014
match_pairs : flat_pat. match_pairs ,
1008
- bindings : flat_pat. bindings ,
1009
- ascriptions : flat_pat. ascriptions ,
1015
+ extra_data : flat_pat. extra_data ,
1010
1016
has_guard,
1011
1017
subcandidates : Vec :: new ( ) ,
1012
1018
otherwise_block : None ,
@@ -1518,9 +1524,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1518
1524
self . merge_trivial_subcandidates ( subcandidate, source_info) ;
1519
1525
1520
1526
// 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 ( ) ;
1524
1529
}
1525
1530
1526
1531
if can_merge {
@@ -1943,7 +1948,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1943
1948
fn bind_and_guard_matched_candidate < ' pat > (
1944
1949
& mut self ,
1945
1950
candidate : Candidate < ' pat , ' tcx > ,
1946
- parent_bindings : & [ ( Vec < Binding < ' tcx > > , Vec < Ascription < ' tcx > > ) ] ,
1951
+ parent_data : & [ PatternExtraData < ' tcx > ] ,
1947
1952
fake_borrows : & [ ( Place < ' tcx > , Local ) ] ,
1948
1953
scrutinee_span : Span ,
1949
1954
arm_match_scope : Option < ( & Arm < ' tcx > , region:: Scope ) > ,
@@ -1954,7 +1959,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1954
1959
1955
1960
debug_assert ! ( candidate. match_pairs. is_empty( ) ) ;
1956
1961
1957
- let candidate_source_info = self . source_info ( candidate. span ) ;
1962
+ let candidate_source_info = self . source_info ( candidate. extra_data . span ) ;
1958
1963
1959
1964
let mut block = candidate. pre_binding_block . unwrap ( ) ;
1960
1965
@@ -1971,11 +1976,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1971
1976
1972
1977
self . ascribe_types (
1973
1978
block,
1974
- parent_bindings
1979
+ parent_data
1975
1980
. iter ( )
1976
- . flat_map ( |( _ , ascriptions ) | ascriptions)
1981
+ . flat_map ( |d| & d . ascriptions )
1977
1982
. cloned ( )
1978
- . chain ( candidate. ascriptions ) ,
1983
+ . chain ( candidate. extra_data . ascriptions ) ,
1979
1984
) ;
1980
1985
1981
1986
// rust-lang/rust#27282: The `autoref` business deserves some
@@ -2063,10 +2068,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2063
2068
&& let Some ( guard) = arm. guard
2064
2069
{
2065
2070
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 ) ;
2070
2073
2071
2074
self . bind_matched_candidate_for_guard ( block, schedule_drops, bindings. clone ( ) ) ;
2072
2075
let guard_frame = GuardFrame {
@@ -2144,10 +2147,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2144
2147
// ```
2145
2148
//
2146
2149
// and that is clearly not correct.
2147
- let by_value_bindings = parent_bindings
2150
+ let by_value_bindings = parent_data
2148
2151
. iter ( )
2149
- . flat_map ( |( bindings , _ ) | bindings)
2150
- . chain ( & candidate. bindings )
2152
+ . flat_map ( |d| & d . bindings )
2153
+ . chain ( & candidate. extra_data . bindings )
2151
2154
. filter ( |binding| matches ! ( binding. binding_mode, BindingMode :: ByValue ) ) ;
2152
2155
// Read all of the by reference bindings to ensure that the
2153
2156
// place they refer to can't be modified by the guard.
@@ -2172,10 +2175,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2172
2175
self . bind_matched_candidate_for_arm_body (
2173
2176
block,
2174
2177
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 ) ,
2179
2179
storages_alive,
2180
2180
) ;
2181
2181
block
0 commit comments