@@ -23,18 +23,12 @@ use rustc_data_structures::indexed_vec::Idx;
23
23
use pattern:: { FieldPattern , Pattern , PatternKind } ;
24
24
use pattern:: { PatternFoldable , PatternFolder } ;
25
25
26
- use rustc:: hir:: def:: Def ;
27
26
use rustc:: hir:: def_id:: DefId ;
28
27
use rustc:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
29
28
30
- use rustc:: hir;
31
- use rustc:: hir:: def:: CtorKind ;
32
- use rustc:: hir:: { Pat , PatKind } ;
29
+ use rustc:: mir:: Field ;
33
30
use rustc:: util:: common:: ErrorReported ;
34
31
35
- use syntax:: ast:: { self , DUMMY_NODE_ID } ;
36
- use syntax:: codemap:: Spanned ;
37
- use syntax:: ptr:: P ;
38
32
use syntax_pos:: { Span , DUMMY_SP } ;
39
33
40
34
use arena:: TypedArena ;
@@ -74,12 +68,6 @@ impl<'tcx> PatternFolder<'tcx> for LiteralExpander {
74
68
}
75
69
}
76
70
77
- pub const DUMMY_WILD_PAT : & ' static Pat = & Pat {
78
- id : DUMMY_NODE_ID ,
79
- node : PatKind :: Wild ,
80
- span : DUMMY_SP
81
- } ;
82
-
83
71
impl < ' tcx > Pattern < ' tcx > {
84
72
fn is_wildcard ( & self ) -> bool {
85
73
match * self . kind {
@@ -224,25 +212,34 @@ pub enum Constructor {
224
212
}
225
213
226
214
impl < ' tcx > Constructor {
227
- fn variant_for_adt ( & self , adt : & ' tcx ty:: AdtDef ) -> & ' tcx ty :: VariantDef {
215
+ fn variant_index_for_adt ( & self , adt : & ' tcx ty:: AdtDef ) -> usize {
228
216
match self {
229
- & Variant ( vid) => adt. variant_with_id ( vid) ,
217
+ & Variant ( vid) => adt. variant_index_with_id ( vid) ,
230
218
& Single => {
231
219
assert_eq ! ( adt. variants. len( ) , 1 ) ;
232
- & adt . variants [ 0 ]
220
+ 0
233
221
}
234
222
_ => bug ! ( "bad constructor {:?} for adt {:?}" , self , adt)
235
223
}
236
224
}
237
225
}
238
226
239
- #[ derive( Clone , PartialEq ) ]
240
- pub enum Usefulness {
227
+ #[ derive( Clone ) ]
228
+ pub enum Usefulness < ' tcx > {
241
229
Useful ,
242
- UsefulWithWitness ( Vec < Witness > ) ,
230
+ UsefulWithWitness ( Vec < Witness < ' tcx > > ) ,
243
231
NotUseful
244
232
}
245
233
234
+ impl < ' tcx > Usefulness < ' tcx > {
235
+ fn is_useful ( & self ) -> bool {
236
+ match * self {
237
+ NotUseful => false ,
238
+ _ => true
239
+ }
240
+ }
241
+ }
242
+
246
243
#[ derive( Copy , Clone ) ]
247
244
pub enum WitnessPreference {
248
245
ConstructWitness ,
@@ -255,39 +252,25 @@ struct PatternContext<'tcx> {
255
252
max_slice_length : usize ,
256
253
}
257
254
258
-
259
- fn const_val_to_expr ( value : & ConstVal ) -> P < hir:: Expr > {
260
- let node = match value {
261
- & ConstVal :: Bool ( b) => ast:: LitKind :: Bool ( b) ,
262
- _ => bug ! ( )
263
- } ;
264
- P ( hir:: Expr {
265
- id : DUMMY_NODE_ID ,
266
- node : hir:: ExprLit ( P ( Spanned { node : node, span : DUMMY_SP } ) ) ,
267
- span : DUMMY_SP ,
268
- attrs : ast:: ThinVec :: new ( ) ,
269
- } )
270
- }
271
-
272
255
/// A stack of patterns in reverse order of construction
273
- #[ derive( Clone , PartialEq , Eq ) ]
274
- pub struct Witness ( Vec < P < Pat > > ) ;
256
+ #[ derive( Clone ) ]
257
+ pub struct Witness < ' tcx > ( Vec < Pattern < ' tcx > > ) ;
275
258
276
- impl Witness {
277
- pub fn single_pattern ( & self ) -> & Pat {
259
+ impl < ' tcx > Witness < ' tcx > {
260
+ pub fn single_pattern ( & self ) -> & Pattern < ' tcx > {
278
261
assert_eq ! ( self . 0 . len( ) , 1 ) ;
279
262
& self . 0 [ 0 ]
280
263
}
281
264
282
- fn push_wild_constructor < ' a , ' tcx > (
265
+ fn push_wild_constructor < ' a > (
283
266
mut self ,
284
267
cx : & MatchCheckCtxt < ' a , ' tcx > ,
285
268
ctor : & Constructor ,
286
269
ty : Ty < ' tcx > )
287
270
-> Self
288
271
{
289
272
let arity = constructor_arity ( cx, ctor, ty) ;
290
- self . 0 . extend ( repeat ( DUMMY_WILD_PAT ) . take ( arity) . map ( |p| P ( p . clone ( ) ) ) ) ;
273
+ self . 0 . extend ( repeat ( cx . wild_pattern ) . take ( arity) . cloned ( ) ) ;
291
274
self . apply_constructor ( cx, ctor, ty)
292
275
}
293
276
@@ -305,7 +288,7 @@ impl Witness {
305
288
///
306
289
/// left_ty: struct X { a: (bool, &'static str), b: usize}
307
290
/// pats: [(false, "foo"), 42] => X { a: (false, "foo"), b: 42 }
308
- fn apply_constructor < ' a , ' tcx > (
291
+ fn apply_constructor < ' a > (
309
292
mut self ,
310
293
cx : & MatchCheckCtxt < ' a , ' tcx > ,
311
294
ctor : & Constructor ,
@@ -318,60 +301,56 @@ impl Witness {
318
301
let mut pats = self . 0 . drain ( len-arity..) . rev ( ) ;
319
302
320
303
match ty. sty {
321
- ty:: TyTuple ( ..) => PatKind :: Tuple ( pats. collect ( ) , None ) ,
322
-
323
- ty:: TyAdt ( adt, _) => {
324
- let v = ctor. variant_for_adt ( adt) ;
325
- let qpath = hir:: QPath :: Resolved ( None , P ( hir:: Path {
326
- span : DUMMY_SP ,
327
- def : Def :: Err ,
328
- segments : vec ! [ hir:: PathSegment :: from_name( v. name) ] . into ( ) ,
329
- } ) ) ;
330
- match v. ctor_kind {
331
- CtorKind :: Fictive => {
332
- let field_pats: hir:: HirVec < _ > = v. fields . iter ( )
333
- . zip ( pats)
334
- . filter ( |& ( _, ref pat) | pat. node != PatKind :: Wild )
335
- . map ( |( field, pat) | Spanned {
336
- span : DUMMY_SP ,
337
- node : hir:: FieldPat {
338
- name : field. name ,
339
- pat : pat,
340
- is_shorthand : false ,
341
- }
342
- } ) . collect ( ) ;
343
- let has_more_fields = field_pats. len ( ) < arity;
344
- PatKind :: Struct ( qpath, field_pats, has_more_fields)
304
+ ty:: TyAdt ( ..) |
305
+ ty:: TyTuple ( ..) => {
306
+ let pats = pats. enumerate ( ) . map ( |( i, p) | {
307
+ FieldPattern {
308
+ field : Field :: new ( i) ,
309
+ pattern : p
345
310
}
346
- CtorKind :: Fn => {
347
- PatKind :: TupleStruct ( qpath, pats. collect ( ) , None )
311
+ } ) . collect ( ) ;
312
+
313
+ if let ty:: TyAdt ( adt, _) = ty. sty {
314
+ if adt. variants . len ( ) > 1 {
315
+ PatternKind :: Variant {
316
+ adt_def : adt,
317
+ variant_index : ctor. variant_index_for_adt ( adt) ,
318
+ subpatterns : pats
319
+ }
320
+ } else {
321
+ PatternKind :: Leaf { subpatterns : pats }
348
322
}
349
- CtorKind :: Const => PatKind :: Path ( qpath)
323
+ } else {
324
+ PatternKind :: Leaf { subpatterns : pats }
350
325
}
351
326
}
352
327
353
- ty:: TyRef ( _ , ty :: TypeAndMut { mutbl , .. } ) => {
354
- PatKind :: Ref ( pats. nth ( 0 ) . unwrap ( ) , mutbl )
328
+ ty:: TyRef ( .. ) => {
329
+ PatternKind :: Deref { subpattern : pats. nth ( 0 ) . unwrap ( ) }
355
330
}
356
331
357
332
ty:: TySlice ( _) | ty:: TyArray ( ..) => {
358
- PatKind :: Slice ( pats. collect ( ) , None , hir:: HirVec :: new ( ) )
333
+ PatternKind :: Slice {
334
+ prefix : pats. collect ( ) ,
335
+ slice : None ,
336
+ suffix : vec ! [ ]
337
+ }
359
338
}
360
339
361
340
_ => {
362
341
match * ctor {
363
- ConstantValue ( ref v) => PatKind :: Lit ( const_val_to_expr ( v ) ) ,
364
- _ => PatKind :: Wild ,
342
+ ConstantValue ( ref v) => PatternKind :: Constant { value : v . clone ( ) } ,
343
+ _ => PatternKind :: Wild ,
365
344
}
366
345
}
367
346
}
368
347
} ;
369
348
370
- self . 0 . push ( P ( hir :: Pat {
371
- id : DUMMY_NODE_ID ,
372
- node : pat ,
373
- span : DUMMY_SP
374
- } ) ) ;
349
+ self . 0 . push ( Pattern {
350
+ ty : ty ,
351
+ span : DUMMY_SP ,
352
+ kind : Box :: new ( pat ) ,
353
+ } ) ;
375
354
376
355
self
377
356
}
@@ -528,13 +507,13 @@ pub fn is_useful<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
528
507
matrix : & Matrix < ' a , ' tcx > ,
529
508
v : & [ & ' a Pattern < ' tcx > ] ,
530
509
witness : WitnessPreference )
531
- -> Usefulness {
510
+ -> Usefulness < ' tcx > {
532
511
let & Matrix ( ref rows) = matrix;
533
512
debug ! ( "is_useful({:?}, {:?})" , matrix, v) ;
534
513
if rows. is_empty ( ) {
535
514
return match witness {
536
515
ConstructWitness => UsefulWithWitness ( vec ! [ Witness (
537
- repeat( DUMMY_WILD_PAT ) . take( v. len( ) ) . map ( |p| P ( p . clone ( ) ) ) . collect( )
516
+ repeat( cx . wild_pattern ) . take( v. len( ) ) . cloned ( ) . collect( )
538
517
) ] ) ,
539
518
LeaveOutWitness => Useful
540
519
} ;
@@ -559,15 +538,15 @@ pub fn is_useful<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
559
538
debug ! ( "is_useful - expanding constructors: {:?}" , constructors) ;
560
539
constructors. into_iter ( ) . map ( |c|
561
540
is_useful_specialized ( cx, matrix, v, c. clone ( ) , pcx. ty , witness)
562
- ) . find ( |result| result != & NotUseful ) . unwrap_or ( NotUseful )
541
+ ) . find ( |result| result. is_useful ( ) ) . unwrap_or ( NotUseful )
563
542
} else {
564
543
debug ! ( "is_useful - expanding wildcard" ) ;
565
544
let constructors = missing_constructors ( cx, matrix, pcx) ;
566
545
debug ! ( "is_useful - missing_constructors = {:?}" , constructors) ;
567
546
if constructors. is_empty ( ) {
568
547
all_constructors ( cx, pcx) . into_iter ( ) . map ( |c| {
569
548
is_useful_specialized ( cx, matrix, v, c. clone ( ) , pcx. ty , witness)
570
- } ) . find ( |result| result != & NotUseful ) . unwrap_or ( NotUseful )
549
+ } ) . find ( |result| result. is_useful ( ) ) . unwrap_or ( NotUseful )
571
550
} else {
572
551
let matrix = rows. iter ( ) . filter_map ( |r| {
573
552
if r[ 0 ] . is_wildcard ( ) {
@@ -597,7 +576,7 @@ fn is_useful_specialized<'a, 'tcx>(
597
576
v : & [ & ' a Pattern < ' tcx > ] ,
598
577
ctor : Constructor ,
599
578
lty : Ty < ' tcx > ,
600
- witness : WitnessPreference ) -> Usefulness
579
+ witness : WitnessPreference ) -> Usefulness < ' tcx >
601
580
{
602
581
let arity = constructor_arity ( cx, & ctor, lty) ;
603
582
let matrix = Matrix ( m. iter ( ) . flat_map ( |r| {
@@ -672,7 +651,7 @@ fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize
672
651
} ,
673
652
ty:: TyRef ( ..) => 1 ,
674
653
ty:: TyAdt ( adt, _) => {
675
- ctor. variant_for_adt ( adt) . fields . len ( )
654
+ adt . variants [ ctor. variant_index_for_adt ( adt) ] . fields . len ( )
676
655
}
677
656
_ => 0
678
657
}
0 commit comments