@@ -95,36 +95,41 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
95
95
96
96
impl < ' pat , ' tcx > MatchPair < ' pat , ' tcx > {
97
97
pub ( in crate :: build) fn new (
98
- mut place : PlaceBuilder < ' tcx > ,
98
+ mut place_builder : PlaceBuilder < ' tcx > ,
99
99
pattern : & ' pat Pat < ' tcx > ,
100
100
cx : & mut Builder < ' _ , ' tcx > ,
101
101
) -> MatchPair < ' pat , ' tcx > {
102
102
// Force the place type to the pattern's type.
103
103
// FIXME(oli-obk): can we use this to simplify slice/array pattern hacks?
104
- if let Some ( resolved) = place . resolve_upvar ( cx) {
105
- place = resolved;
104
+ if let Some ( resolved) = place_builder . resolve_upvar ( cx) {
105
+ place_builder = resolved;
106
106
}
107
107
108
108
// Only add the OpaqueCast projection if the given place is an opaque type and the
109
109
// expected type from the pattern is not.
110
- let may_need_cast = match place . base ( ) {
110
+ let may_need_cast = match place_builder . base ( ) {
111
111
PlaceBase :: Local ( local) => {
112
- let ty = Place :: ty_from ( local, place. projection ( ) , & cx. local_decls , cx. tcx ) . ty ;
112
+ let ty =
113
+ Place :: ty_from ( local, place_builder. projection ( ) , & cx. local_decls , cx. tcx ) . ty ;
113
114
ty != pattern. ty && ty. has_opaque_types ( )
114
115
}
115
116
_ => true ,
116
117
} ;
117
118
if may_need_cast {
118
- place = place . project ( ProjectionElem :: OpaqueCast ( pattern. ty ) ) ;
119
+ place_builder = place_builder . project ( ProjectionElem :: OpaqueCast ( pattern. ty ) ) ;
119
120
}
120
121
122
+ let place = place_builder. try_to_place ( cx) ;
121
123
let default_irrefutable = || TestCase :: Irrefutable { binding : None , ascription : None } ;
122
124
let mut subpairs = Vec :: new ( ) ;
123
125
let test_case = match pattern. kind {
124
126
PatKind :: Never | PatKind :: Wild | PatKind :: Error ( _) => default_irrefutable ( ) ,
125
- PatKind :: Or { ref pats } => TestCase :: Or {
126
- pats : pats. iter ( ) . map ( |pat| FlatPat :: new ( place. clone ( ) , pat, cx) ) . collect ( ) ,
127
- } ,
127
+ PatKind :: Or { ref pats } => {
128
+ let pats: Box < [ _ ] > =
129
+ pats. iter ( ) . map ( |pat| FlatPat :: new ( place_builder. clone ( ) , pat, cx) ) . collect ( ) ;
130
+ let simple = pats. iter ( ) . all ( |fpat| fpat. simple ) ;
131
+ TestCase :: Or { pats, simple }
132
+ }
128
133
129
134
PatKind :: Range ( ref range) => {
130
135
if range. is_full_range ( cx. tcx ) == Some ( true ) {
@@ -142,13 +147,13 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
142
147
..
143
148
} => {
144
149
// Apply the type ascription to the value at `match_pair.place`
145
- let ascription = place. try_to_place ( cx ) . map ( |source| super :: Ascription {
150
+ let ascription = place. map ( |source| super :: Ascription {
146
151
annotation : annotation. clone ( ) ,
147
152
source,
148
153
variance,
149
154
} ) ;
150
155
151
- subpairs. push ( MatchPair :: new ( place . clone ( ) , subpattern, cx) ) ;
156
+ subpairs. push ( MatchPair :: new ( place_builder , subpattern, cx) ) ;
152
157
TestCase :: Irrefutable { ascription, binding : None }
153
158
}
154
159
@@ -161,7 +166,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
161
166
ref subpattern,
162
167
is_primary : _,
163
168
} => {
164
- let binding = place. try_to_place ( cx ) . map ( |source| super :: Binding {
169
+ let binding = place. map ( |source| super :: Binding {
165
170
span : pattern. span ,
166
171
source,
167
172
var_id : var,
@@ -170,14 +175,14 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
170
175
171
176
if let Some ( subpattern) = subpattern. as_ref ( ) {
172
177
// this is the `x @ P` case; have to keep matching against `P` now
173
- subpairs. push ( MatchPair :: new ( place . clone ( ) , subpattern, cx) ) ;
178
+ subpairs. push ( MatchPair :: new ( place_builder , subpattern, cx) ) ;
174
179
}
175
180
TestCase :: Irrefutable { ascription : None , binding }
176
181
}
177
182
178
183
PatKind :: InlineConstant { subpattern : ref pattern, def, .. } => {
179
184
// Apply a type ascription for the inline constant to the value at `match_pair.place`
180
- let ascription = place. try_to_place ( cx ) . map ( |source| {
185
+ let ascription = place. map ( |source| {
181
186
let span = pattern. span ;
182
187
let parent_id = cx. tcx . typeck_root_def_id ( cx. def_id . to_def_id ( ) ) ;
183
188
let args = ty:: InlineConstArgs :: new (
@@ -203,16 +208,16 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
203
208
super :: Ascription { annotation, source, variance : ty:: Contravariant }
204
209
} ) ;
205
210
206
- subpairs. push ( MatchPair :: new ( place . clone ( ) , pattern, cx) ) ;
211
+ subpairs. push ( MatchPair :: new ( place_builder , pattern, cx) ) ;
207
212
TestCase :: Irrefutable { ascription, binding : None }
208
213
}
209
214
210
215
PatKind :: Array { ref prefix, ref slice, ref suffix } => {
211
- cx. prefix_slice_suffix ( & mut subpairs, & place , prefix, slice, suffix) ;
216
+ cx. prefix_slice_suffix ( & mut subpairs, & place_builder , prefix, slice, suffix) ;
212
217
default_irrefutable ( )
213
218
}
214
219
PatKind :: Slice { ref prefix, ref slice, ref suffix } => {
215
- cx. prefix_slice_suffix ( & mut subpairs, & place , prefix, slice, suffix) ;
220
+ cx. prefix_slice_suffix ( & mut subpairs, & place_builder , prefix, slice, suffix) ;
216
221
217
222
if prefix. is_empty ( ) && slice. is_some ( ) && suffix. is_empty ( ) {
218
223
default_irrefutable ( )
@@ -225,7 +230,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
225
230
}
226
231
227
232
PatKind :: Variant { adt_def, variant_index, args, ref subpatterns } => {
228
- let downcast_place = place . clone ( ) . downcast ( adt_def, variant_index) ; // `(x as Variant)`
233
+ let downcast_place = place_builder . downcast ( adt_def, variant_index) ; // `(x as Variant)`
229
234
subpairs = cx. field_match_pairs ( downcast_place, subpatterns) ;
230
235
231
236
let irrefutable = adt_def. variants ( ) . iter_enumerated ( ) . all ( |( i, v) | {
@@ -247,19 +252,24 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
247
252
}
248
253
249
254
PatKind :: Leaf { ref subpatterns } => {
250
- subpairs = cx. field_match_pairs ( place . clone ( ) , subpatterns) ;
255
+ subpairs = cx. field_match_pairs ( place_builder , subpatterns) ;
251
256
default_irrefutable ( )
252
257
}
253
258
254
259
PatKind :: Deref { ref subpattern } => {
255
- let place_builder = place. clone ( ) . deref ( ) ;
256
- subpairs. push ( MatchPair :: new ( place_builder, subpattern, cx) ) ;
260
+ subpairs. push ( MatchPair :: new ( place_builder. deref ( ) , subpattern, cx) ) ;
257
261
default_irrefutable ( )
258
262
}
259
263
} ;
260
264
261
265
MatchPair { place, test_case, subpairs, pattern }
262
266
}
267
+
268
+ /// Whether this recursively contains no bindings or ascriptions.
269
+ pub ( super ) fn is_simple ( & self ) -> bool {
270
+ !matches ! ( self . test_case, TestCase :: Or { simple: false , .. } )
271
+ && self . subpairs . iter ( ) . all ( |p| p. is_simple ( ) )
272
+ }
263
273
}
264
274
265
275
pub ( super ) struct FakeBorrowCollector < ' a , ' b , ' tcx > {
@@ -283,7 +293,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
283
293
for binding in & candidate. bindings {
284
294
self . visit_binding ( binding) ;
285
295
}
286
- for match_pair in & candidate. match_pairs {
296
+ for match_pair in candidate. match_pairs . values ( ) {
287
297
self . visit_match_pair ( match_pair) ;
288
298
}
289
299
}
@@ -292,7 +302,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
292
302
for binding in & flat_pat. bindings {
293
303
self . visit_binding ( binding) ;
294
304
}
295
- for match_pair in & flat_pat. match_pairs {
305
+ for match_pair in flat_pat. match_pairs . values ( ) {
296
306
self . visit_match_pair ( match_pair) ;
297
307
}
298
308
}
@@ -304,8 +314,8 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
304
314
}
305
315
} else {
306
316
// Insert a Shallow borrow of any place that is switched on.
307
- if let Some ( resolved_place ) = match_pair. place . try_to_place ( self . cx ) {
308
- self . fake_borrows . insert ( resolved_place ) ;
317
+ if let Some ( place ) = match_pair. place {
318
+ self . fake_borrows . insert ( place ) ;
309
319
}
310
320
311
321
for subpair in & match_pair. subpairs {
0 commit comments