@@ -993,13 +993,13 @@ struct PatternExtraData<'tcx> {
993993 /// Whether this corresponds to a never pattern.
994994 is_never : bool ,
995995
996- /// [`ExprId`]s of subpattern conditions
997- guard_patterns : Vec < OrderedPatternData < ExprId > > ,
996+ /// [`ExprId`]s of guards that must be evaluated for this pattern
997+ guards : Vec < OrderedPatternData < ExprId > > ,
998998}
999999
10001000impl < ' tcx > PatternExtraData < ' tcx > {
10011001 fn is_empty ( & self ) -> bool {
1002- self . bindings . is_empty ( ) && self . ascriptions . is_empty ( ) && self . guard_patterns . is_empty ( )
1002+ self . bindings . is_empty ( ) && self . ascriptions . is_empty ( ) && self . guards . is_empty ( )
10031003 }
10041004}
10051005
@@ -1087,8 +1087,12 @@ struct Candidate<'tcx> {
10871087 /// `otherwise_block`.
10881088 ///
10891089 /// ---
1090- /// For subcandidates, this is copied from the parent candidate
1091- guards : Vec < ExprId > ,
1090+ /// For subcandidates, this is copied from the parent candidate, so it indicates
1091+ /// whether the enclosing match arm has a guard.
1092+ under_guard : bool ,
1093+
1094+ /// Whether subcandidates contain guards.
1095+ contains_guards : bool ,
10921096
10931097 /// Holds extra pattern data that was prepared by [`FlatPat`], including bindings and
10941098 /// ascriptions that must be established if this candidate succeeds.
@@ -1125,20 +1129,24 @@ impl<'tcx> Candidate<'tcx> {
11251129 ) -> Self {
11261130 // Use `FlatPat` to build simplified match pairs, then immediately
11271131 // incorporate them into a new candidate.
1128- let flat_pat = FlatPat :: new ( place, pattern, cx) ;
1129- let mut guards = Vec :: new ( ) ;
1132+ let mut flat_pat = FlatPat :: new ( place, pattern, cx) ;
1133+ let mut under_guard = false ;
11301134 if let HasMatchGuard :: Yes ( g) = guard {
1131- guards. push ( g) ;
1135+ under_guard = true ;
1136+ flat_pat. extra_data . guards . push ( OrderedPatternData :: One ( g) ) ;
11321137 }
1133- Self :: from_flat_pat ( flat_pat, guards )
1138+ Self :: from_flat_pat ( flat_pat, under_guard )
11341139 }
11351140
11361141 /// Incorporates an already-simplified [`FlatPat`] into a new candidate.
1137- fn from_flat_pat ( flat_pat : FlatPat < ' tcx > , guards : Vec < ExprId > ) -> Self {
1142+ fn from_flat_pat ( flat_pat : FlatPat < ' tcx > , under_guard : bool ) -> Self {
1143+ let contains_guards = flat_pat. extra_data . guards . len ( ) >= 2
1144+ || flat_pat. extra_data . guards . len ( ) == 1 && !under_guard;
11381145 let mut this = Candidate {
11391146 match_pairs : flat_pat. match_pairs ,
11401147 extra_data : flat_pat. extra_data ,
1141- guards,
1148+ under_guard,
1149+ contains_guards,
11421150 subcandidates : Vec :: new ( ) ,
11431151 or_span : None ,
11441152 otherwise_block : None ,
@@ -1494,12 +1502,9 @@ impl<'tcx> MatchTreeSubBranch<'tcx> {
14941502 . chain ( candidate. extra_data . ascriptions )
14951503 . collect ( ) ,
14961504 guards : sub_branch_ordered_pat_data (
1497- parent_data. iter ( ) . map ( |parent| parent. guard_patterns . as_slice ( ) ) ,
1498- & candidate. extra_data . guard_patterns ,
1499- )
1500- . into_iter ( )
1501- . chain ( candidate. guards )
1502- . collect ( ) ,
1505+ parent_data. iter ( ) . map ( |parent| parent. guards . as_slice ( ) ) ,
1506+ & candidate. extra_data . guards ,
1507+ ) ,
15031508 is_never : candidate. extra_data . is_never ,
15041509 }
15051510 }
@@ -1659,7 +1664,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
16591664 Exhaustive :: No => Some ( otherwise_block) ,
16601665 } ;
16611666 for candidate in candidates. iter_mut ( ) . rev ( ) {
1662- let has_guard = ! candidate. guards . is_empty ( ) ;
1667+ let has_guard = candidate. under_guard || candidate . contains_guards ;
16631668 candidate. visit_leaves_rev ( |leaf_candidate| {
16641669 if let Some ( next_candidate_start_block) = next_candidate_start_block {
16651670 let source_info = self . source_info ( leaf_candidate. extra_data . span ) ;
@@ -2004,10 +2009,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20042009 let TestableCase :: Or { pats } = match_pair. testable_case else { bug ! ( ) } ;
20052010 debug ! ( "expanding or-pattern: candidate={:#?}\n pats={:#?}" , candidate, pats) ;
20062011 candidate. or_span = Some ( match_pair. pattern_span ) ;
2007- candidate. subcandidates = pats
2008- . into_iter ( )
2009- . map ( |flat_pat| Candidate :: from_flat_pat ( flat_pat, candidate. guards . clone ( ) ) )
2010- . collect ( ) ;
2012+ candidate. subcandidates =
2013+ pats. into_iter ( ) . map ( |flat_pat| Candidate :: from_flat_pat ( flat_pat, false ) ) . collect ( ) ;
20112014 candidate. subcandidates [ 0 ] . false_edge_start_block = candidate. false_edge_start_block ;
20122015 }
20132016
@@ -2070,7 +2073,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20702073 /// in match tree lowering.
20712074 fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' tcx > ) {
20722075 assert ! ( !candidate. subcandidates. is_empty( ) ) ;
2073- if ! candidate. guards . is_empty ( ) || ! candidate. extra_data . guard_patterns . is_empty ( ) {
2076+ if candidate. under_guard || candidate. contains_guards {
20742077 // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
20752078 return ;
20762079 }
@@ -2190,7 +2193,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21902193 // directly to `last_otherwise`. If there is a guard,
21912194 // `leaf_candidate.otherwise_block` can be reached by guard failure as well, so we
21922195 // can't skip `Q`.
2193- let or_otherwise = if ! leaf_candidate. guards . is_empty ( ) {
2196+ let or_otherwise = if leaf_candidate. under_guard {
21942197 leaf_candidate. otherwise_block . unwrap ( )
21952198 } else {
21962199 last_otherwise. unwrap ( )
0 commit comments