@@ -23,18 +23,12 @@ use rustc_data_structures::indexed_vec::Idx;
2323use pattern:: { FieldPattern , Pattern , PatternKind } ;
2424use pattern:: { PatternFoldable , PatternFolder } ;
2525
26- use rustc:: hir:: def:: Def ;
2726use rustc:: hir:: def_id:: DefId ;
2827use rustc:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
2928
30- use rustc:: hir;
31- use rustc:: hir:: def:: CtorKind ;
32- use rustc:: hir:: { Pat , PatKind } ;
29+ use rustc:: mir:: Field ;
3330use rustc:: util:: common:: ErrorReported ;
3431
35- use syntax:: ast:: { self , DUMMY_NODE_ID } ;
36- use syntax:: codemap:: Spanned ;
37- use syntax:: ptr:: P ;
3832use syntax_pos:: { Span , DUMMY_SP } ;
3933
4034use arena:: TypedArena ;
@@ -74,12 +68,6 @@ impl<'tcx> PatternFolder<'tcx> for LiteralExpander {
7468 }
7569}
7670
77- pub const DUMMY_WILD_PAT : & ' static Pat = & Pat {
78- id : DUMMY_NODE_ID ,
79- node : PatKind :: Wild ,
80- span : DUMMY_SP
81- } ;
82-
8371impl < ' tcx > Pattern < ' tcx > {
8472 fn is_wildcard ( & self ) -> bool {
8573 match * self . kind {
@@ -224,25 +212,34 @@ pub enum Constructor {
224212}
225213
226214impl < ' 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 {
228216 match self {
229- & Variant ( vid) => adt. variant_with_id ( vid) ,
217+ & Variant ( vid) => adt. variant_index_with_id ( vid) ,
230218 & Single => {
231219 assert_eq ! ( adt. variants. len( ) , 1 ) ;
232- & adt . variants [ 0 ]
220+ 0
233221 }
234222 _ => bug ! ( "bad constructor {:?} for adt {:?}" , self , adt)
235223 }
236224 }
237225}
238226
239- #[ derive( Clone , PartialEq ) ]
240- pub enum Usefulness {
227+ #[ derive( Clone ) ]
228+ pub enum Usefulness < ' tcx > {
241229 Useful ,
242- UsefulWithWitness ( Vec < Witness > ) ,
230+ UsefulWithWitness ( Vec < Witness < ' tcx > > ) ,
243231 NotUseful
244232}
245233
234+ impl < ' tcx > Usefulness < ' tcx > {
235+ fn is_useful ( & self ) -> bool {
236+ match * self {
237+ NotUseful => false ,
238+ _ => true
239+ }
240+ }
241+ }
242+
246243#[ derive( Copy , Clone ) ]
247244pub enum WitnessPreference {
248245 ConstructWitness ,
@@ -255,39 +252,25 @@ struct PatternContext<'tcx> {
255252 max_slice_length : usize ,
256253}
257254
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-
272255/// 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 > > ) ;
275258
276- impl Witness {
277- pub fn single_pattern ( & self ) -> & Pat {
259+ impl < ' tcx > Witness < ' tcx > {
260+ pub fn single_pattern ( & self ) -> & Pattern < ' tcx > {
278261 assert_eq ! ( self . 0 . len( ) , 1 ) ;
279262 & self . 0 [ 0 ]
280263 }
281264
282- fn push_wild_constructor < ' a , ' tcx > (
265+ fn push_wild_constructor < ' a > (
283266 mut self ,
284267 cx : & MatchCheckCtxt < ' a , ' tcx > ,
285268 ctor : & Constructor ,
286269 ty : Ty < ' tcx > )
287270 -> Self
288271 {
289272 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 ( ) ) ;
291274 self . apply_constructor ( cx, ctor, ty)
292275 }
293276
@@ -305,7 +288,7 @@ impl Witness {
305288 ///
306289 /// left_ty: struct X { a: (bool, &'static str), b: usize}
307290 /// pats: [(false, "foo"), 42] => X { a: (false, "foo"), b: 42 }
308- fn apply_constructor < ' a , ' tcx > (
291+ fn apply_constructor < ' a > (
309292 mut self ,
310293 cx : & MatchCheckCtxt < ' a , ' tcx > ,
311294 ctor : & Constructor ,
@@ -318,60 +301,56 @@ impl Witness {
318301 let mut pats = self . 0 . drain ( len-arity..) . rev ( ) ;
319302
320303 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
345310 }
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 }
348322 }
349- CtorKind :: Const => PatKind :: Path ( qpath)
323+ } else {
324+ PatternKind :: Leaf { subpatterns : pats }
350325 }
351326 }
352327
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 ( ) }
355330 }
356331
357332 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+ }
359338 }
360339
361340 _ => {
362341 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 ,
365344 }
366345 }
367346 }
368347 } ;
369348
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+ } ) ;
375354
376355 self
377356 }
@@ -528,13 +507,13 @@ pub fn is_useful<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
528507 matrix : & Matrix < ' a , ' tcx > ,
529508 v : & [ & ' a Pattern < ' tcx > ] ,
530509 witness : WitnessPreference )
531- -> Usefulness {
510+ -> Usefulness < ' tcx > {
532511 let & Matrix ( ref rows) = matrix;
533512 debug ! ( "is_useful({:?}, {:?})" , matrix, v) ;
534513 if rows. is_empty ( ) {
535514 return match witness {
536515 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( )
538517 ) ] ) ,
539518 LeaveOutWitness => Useful
540519 } ;
@@ -559,15 +538,15 @@ pub fn is_useful<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
559538 debug ! ( "is_useful - expanding constructors: {:?}" , constructors) ;
560539 constructors. into_iter ( ) . map ( |c|
561540 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 )
563542 } else {
564543 debug ! ( "is_useful - expanding wildcard" ) ;
565544 let constructors = missing_constructors ( cx, matrix, pcx) ;
566545 debug ! ( "is_useful - missing_constructors = {:?}" , constructors) ;
567546 if constructors. is_empty ( ) {
568547 all_constructors ( cx, pcx) . into_iter ( ) . map ( |c| {
569548 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 )
571550 } else {
572551 let matrix = rows. iter ( ) . filter_map ( |r| {
573552 if r[ 0 ] . is_wildcard ( ) {
@@ -597,7 +576,7 @@ fn is_useful_specialized<'a, 'tcx>(
597576 v : & [ & ' a Pattern < ' tcx > ] ,
598577 ctor : Constructor ,
599578 lty : Ty < ' tcx > ,
600- witness : WitnessPreference ) -> Usefulness
579+ witness : WitnessPreference ) -> Usefulness < ' tcx >
601580{
602581 let arity = constructor_arity ( cx, & ctor, lty) ;
603582 let matrix = Matrix ( m. iter ( ) . flat_map ( |r| {
@@ -672,7 +651,7 @@ fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize
672651 } ,
673652 ty:: TyRef ( ..) => 1 ,
674653 ty:: TyAdt ( adt, _) => {
675- ctor. variant_for_adt ( adt) . fields . len ( )
654+ adt . variants [ ctor. variant_index_for_adt ( adt) ] . fields . len ( )
676655 }
677656 _ => 0
678657 }
0 commit comments