66//! - `place @ (P1, P2)` can be simplified to `[place.0 @ P1, place.1 @ P2]`
77//! - `place @ x` can be simplified to `[]` by binding `x` to `place`
88//!
9- //! The `simplify_candidate ` routine just repeatedly applies these
9+ //! The `simplify_match_pairs ` routine just repeatedly applies these
1010//! sort of simplifications until there is nothing left to
1111//! simplify. Match pairs cannot be simplified if they require some
1212//! sort of test: for example, testing which variant an enum is, or
@@ -22,10 +22,15 @@ use rustc_middle::ty;
2222use std:: mem;
2323
2424impl < ' a , ' tcx > Builder < ' a , ' tcx > {
25- /// Simplify a candidate so that all match pairs require a test.
26- #[ instrument( skip( self , candidate) , level = "debug" ) ]
27- pub ( super ) fn simplify_candidate < ' pat > ( & mut self , candidate : & mut Candidate < ' pat , ' tcx > ) {
28- debug ! ( "{candidate:#?}" ) ;
25+ /// Simplify a list of match pairs so they all require a test. Stores relevant bindings and
26+ /// ascriptions in the provided `Vec`s.
27+ #[ instrument( skip( self ) , level = "debug" ) ]
28+ pub ( super ) fn simplify_match_pairs < ' pat > (
29+ & mut self ,
30+ match_pairs : & mut Vec < MatchPair < ' pat , ' tcx > > ,
31+ candidate_bindings : & mut Vec < Binding < ' tcx > > ,
32+ candidate_ascriptions : & mut Vec < Ascription < ' tcx > > ,
33+ ) {
2934 // In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
3035 // bindings in `pat` before `x`. E.g. (#69971):
3136 //
@@ -53,60 +58,70 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5358 // bindings in iter 2: [6, 7]
5459 //
5560 // final bindings: [6, 7, 4, 5, 1, 2, 3]
56- let mut accumulated_bindings = mem:: take ( & mut candidate . bindings ) ;
61+ let mut accumulated_bindings = mem:: take ( candidate_bindings ) ;
5762 // Repeatedly simplify match pairs until fixed point is reached
5863 loop {
5964 let mut changed = false ;
60- for match_pair in mem:: take ( & mut candidate. match_pairs ) {
61- match self . simplify_match_pair ( match_pair, candidate) {
65+ for match_pair in mem:: take ( match_pairs) {
66+ match self . simplify_match_pair (
67+ match_pair,
68+ candidate_bindings,
69+ candidate_ascriptions,
70+ match_pairs,
71+ ) {
6272 Ok ( ( ) ) => {
6373 changed = true ;
6474 }
6575 Err ( match_pair) => {
66- candidate . match_pairs . push ( match_pair) ;
76+ match_pairs. push ( match_pair) ;
6777 }
6878 }
6979 }
7080
7181 // This does: accumulated_bindings = candidate.bindings.take() ++ accumulated_bindings
72- candidate . bindings . extend_from_slice ( & accumulated_bindings) ;
73- mem:: swap ( & mut candidate . bindings , & mut accumulated_bindings) ;
74- candidate . bindings . clear ( ) ;
82+ candidate_bindings . extend_from_slice ( & accumulated_bindings) ;
83+ mem:: swap ( candidate_bindings , & mut accumulated_bindings) ;
84+ candidate_bindings . clear ( ) ;
7585
7686 if !changed {
7787 // If we were not able to simplify anymore, done.
7888 break ;
7989 }
8090 }
8191
82- // Store computed bindings back in `candidate `.
83- mem:: swap ( & mut candidate . bindings , & mut accumulated_bindings) ;
92+ // Store computed bindings back in `candidate_bindings `.
93+ mem:: swap ( candidate_bindings , & mut accumulated_bindings) ;
8494
8595 // Move or-patterns to the end, because they can result in us
8696 // creating additional candidates, so we want to test them as
8797 // late as possible.
88- candidate . match_pairs . sort_by_key ( |pair| matches ! ( pair. pattern. kind, PatKind :: Or { .. } ) ) ;
89- debug ! ( simplified = ?candidate , "simplify_candidate " ) ;
98+ match_pairs. sort_by_key ( |pair| matches ! ( pair. pattern. kind, PatKind :: Or { .. } ) ) ;
99+ debug ! ( simplified = ?match_pairs , "simplify_match_pairs " ) ;
90100 }
91101
92102 /// Given `candidate` that has a single or-pattern for its match-pairs,
93103 /// creates a fresh candidate for each of its input subpatterns passed via
94104 /// `pats`.
95105 pub ( super ) fn create_or_subcandidates < ' pat > (
96106 & mut self ,
97- candidate : & Candidate < ' pat , ' tcx > ,
98107 place : & PlaceBuilder < ' tcx > ,
99108 pats : & ' pat [ Box < Pat < ' tcx > > ] ,
109+ has_guard : bool ,
100110 ) -> Vec < Candidate < ' pat , ' tcx > > {
101111 pats. iter ( )
102112 . map ( |box pat| {
103- let mut candidate = Candidate :: new ( place. clone ( ) , pat, candidate. has_guard , self ) ;
104- self . simplify_candidate ( & mut candidate) ;
113+ let mut candidate = Candidate :: new ( place. clone ( ) , pat, has_guard, self ) ;
114+ self . simplify_match_pairs (
115+ & mut candidate. match_pairs ,
116+ & mut candidate. bindings ,
117+ & mut candidate. ascriptions ,
118+ ) ;
105119
106120 if let [ MatchPair { pattern : Pat { kind : PatKind :: Or { pats } , .. } , place, .. } ] =
107121 & * candidate. match_pairs
108122 {
109- candidate. subcandidates = self . create_or_subcandidates ( & candidate, place, pats) ;
123+ candidate. subcandidates =
124+ self . create_or_subcandidates ( place, pats, candidate. has_guard ) ;
110125 candidate. match_pairs . pop ( ) ;
111126 }
112127 candidate
@@ -122,7 +137,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
122137 fn simplify_match_pair < ' pat > (
123138 & mut self ,
124139 match_pair : MatchPair < ' pat , ' tcx > ,
125- candidate : & mut Candidate < ' pat , ' tcx > ,
140+ bindings : & mut Vec < Binding < ' tcx > > ,
141+ ascriptions : & mut Vec < Ascription < ' tcx > > ,
142+ match_pairs : & mut Vec < MatchPair < ' pat , ' tcx > > ,
126143 ) -> Result < ( ) , MatchPair < ' pat , ' tcx > > {
127144 match match_pair. pattern . kind {
128145 PatKind :: AscribeUserType {
@@ -131,14 +148,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
131148 } => {
132149 // Apply the type ascription to the value at `match_pair.place`
133150 if let Some ( source) = match_pair. place . try_to_place ( self ) {
134- candidate . ascriptions . push ( Ascription {
151+ ascriptions. push ( Ascription {
135152 annotation : annotation. clone ( ) ,
136153 source,
137154 variance,
138155 } ) ;
139156 }
140157
141- candidate . match_pairs . push ( MatchPair :: new ( match_pair. place , subpattern, self ) ) ;
158+ match_pairs. push ( MatchPair :: new ( match_pair. place , subpattern, self ) ) ;
142159
143160 Ok ( ( ) )
144161 }
@@ -158,7 +175,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
158175 is_primary : _,
159176 } => {
160177 if let Some ( source) = match_pair. place . try_to_place ( self ) {
161- candidate . bindings . push ( Binding {
178+ bindings. push ( Binding {
162179 span : match_pair. pattern . span ,
163180 source,
164181 var_id : var,
@@ -168,7 +185,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
168185
169186 if let Some ( subpattern) = subpattern. as_ref ( ) {
170187 // this is the `x @ P` case; have to keep matching against `P` now
171- candidate . match_pairs . push ( MatchPair :: new ( match_pair. place , subpattern, self ) ) ;
188+ match_pairs. push ( MatchPair :: new ( match_pair. place , subpattern, self ) ) ;
172189 }
173190
174191 Ok ( ( ) )
@@ -211,13 +228,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
211228 span,
212229 user_ty : Box :: new ( user_ty) ,
213230 } ;
214- candidate . ascriptions . push ( Ascription {
231+ ascriptions. push ( Ascription {
215232 annotation,
216233 source,
217234 variance : ty:: Contravariant ,
218235 } ) ;
219236 }
220- candidate . match_pairs . push ( MatchPair :: new ( match_pair. place , pattern, self ) ) ;
237+ match_pairs. push ( MatchPair :: new ( match_pair. place , pattern, self ) ) ;
221238
222239 Ok ( ( ) )
223240 }
@@ -233,13 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
233250 PatKind :: Slice { ref prefix, ref slice, ref suffix } => {
234251 if prefix. is_empty ( ) && slice. is_some ( ) && suffix. is_empty ( ) {
235252 // irrefutable
236- self . prefix_slice_suffix (
237- & mut candidate. match_pairs ,
238- & match_pair. place ,
239- prefix,
240- slice,
241- suffix,
242- ) ;
253+ self . prefix_slice_suffix ( match_pairs, & match_pair. place , prefix, slice, suffix) ;
243254 Ok ( ( ) )
244255 } else {
245256 Err ( match_pair)
@@ -260,35 +271,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
260271 || !adt_def. is_variant_list_non_exhaustive ( ) ) ;
261272 if irrefutable {
262273 let place_builder = match_pair. place . downcast ( adt_def, variant_index) ;
263- candidate
264- . match_pairs
265- . extend ( self . field_match_pairs ( place_builder, subpatterns) ) ;
274+ match_pairs. extend ( self . field_match_pairs ( place_builder, subpatterns) ) ;
266275 Ok ( ( ) )
267276 } else {
268277 Err ( match_pair)
269278 }
270279 }
271280
272281 PatKind :: Array { ref prefix, ref slice, ref suffix } => {
273- self . prefix_slice_suffix (
274- & mut candidate. match_pairs ,
275- & match_pair. place ,
276- prefix,
277- slice,
278- suffix,
279- ) ;
282+ self . prefix_slice_suffix ( match_pairs, & match_pair. place , prefix, slice, suffix) ;
280283 Ok ( ( ) )
281284 }
282285
283286 PatKind :: Leaf { ref subpatterns } => {
284287 // tuple struct, match subpats (if any)
285- candidate . match_pairs . extend ( self . field_match_pairs ( match_pair. place , subpatterns) ) ;
288+ match_pairs. extend ( self . field_match_pairs ( match_pair. place , subpatterns) ) ;
286289 Ok ( ( ) )
287290 }
288291
289292 PatKind :: Deref { ref subpattern } => {
290293 let place_builder = match_pair. place . deref ( ) ;
291- candidate . match_pairs . push ( MatchPair :: new ( place_builder, subpattern, self ) ) ;
294+ match_pairs. push ( MatchPair :: new ( place_builder, subpattern, self ) ) ;
292295 Ok ( ( ) )
293296 }
294297
0 commit comments