@@ -481,161 +481,170 @@ fn wild() -> @pat {
481
481
@pat { id: 0 , node: pat_wild, span: ast_util:: dummy_sp ( ) }
482
482
}
483
483
484
- fn specialize( cx : @MatchCheckCtxt , r : ~[ @pat] , ctor_id : ctor , arity : uint ,
484
+ fn specialize( cx : @MatchCheckCtxt , + r : ~[ @pat] , ctor_id : ctor , arity : uint ,
485
485
left_ty : ty:: t ) -> Option <~[ @pat] > {
486
- let r0 = raw_pat ( r[ 0 ] ) ;
487
- match /*bad*/ copy r0. node {
488
- pat_wild => Some ( vec:: append ( vec:: from_elem ( arity, wild ( ) ) ,
489
- vec:: tail ( r) ) ) ,
490
- pat_ident( _, _, _) => {
491
- match cx. tcx . def_map . find ( r0. id ) {
492
- Some ( def_variant( _, id) ) => {
493
- if variant ( id) == ctor_id { Some ( vec:: tail ( r) ) }
494
- else { None }
495
- }
496
- Some ( def_const( did) ) => {
497
- let const_expr = lookup_const_by_id ( cx. tcx , did) . get ( ) ;
498
- let e_v = eval_const_expr ( cx. tcx , const_expr) ;
499
- let match_ = match ctor_id {
500
- val( ref v) => compare_const_vals ( e_v, ( * v) ) == 0 ,
501
- range( ref c_lo, ref c_hi) => {
502
- compare_const_vals ( ( * c_lo) , e_v) >= 0 &&
503
- compare_const_vals ( ( * c_hi) , e_v) <= 0
486
+ // Sad, but I can't get rid of this easily
487
+ let mut r0 = copy * raw_pat ( r[ 0 ] ) ;
488
+ match r0 {
489
+ pat { id : pat_id, node : n, span : pat_span} =>
490
+ match n {
491
+ pat_wild => Some ( vec:: append ( vec:: from_elem ( arity, wild ( ) ) ,
492
+ vec:: tail ( r) ) ) ,
493
+ pat_ident( _, _, _) => {
494
+ match cx. tcx . def_map . find ( pat_id) {
495
+ Some ( def_variant( _, id) ) => {
496
+ if variant ( id) == ctor_id { Some ( vec:: tail ( r) ) }
497
+ else { None }
498
+ }
499
+ Some ( def_const( did) ) => {
500
+ let const_expr =
501
+ lookup_const_by_id ( cx. tcx , did) . get ( ) ;
502
+ let e_v = eval_const_expr ( cx. tcx , const_expr) ;
503
+ let match_ = match ctor_id {
504
+ val( ref v) => compare_const_vals ( e_v, ( * v) ) == 0 ,
505
+ range( ref c_lo, ref c_hi) => {
506
+ compare_const_vals ( ( * c_lo) , e_v) >= 0 &&
507
+ compare_const_vals ( ( * c_hi) , e_v) <= 0
508
+ }
509
+ single => true ,
510
+ _ => fail ~"type error"
511
+ } ;
512
+ if match_ { Some ( vec:: tail ( r) ) } else { None }
513
+ }
514
+ _ => Some ( vec:: append ( vec:: from_elem ( arity, wild ( ) ) ,
515
+ vec:: tail ( r) ) )
504
516
}
505
- single => true ,
506
- _ => fail ~"type error"
507
- } ;
508
- if match_ { Some ( vec:: tail ( r) ) } else { None }
509
- }
510
- _ => Some ( vec:: append ( vec:: from_elem ( arity, wild ( ) ) , vec:: tail ( r) ) )
511
- }
512
- }
513
- pat_enum( _, args) => {
514
- match cx. tcx . def_map . get ( r0. id ) {
515
- def_variant( _, id) if variant ( id) == ctor_id => {
516
- let args = match args {
517
- Some ( args) => args,
518
- None => vec:: from_elem ( arity, wild ( ) )
519
- } ;
520
- Some ( vec:: append ( args, vec:: tail ( r) ) )
521
- }
522
- def_variant( _, _) => None ,
523
- def_struct( * ) => {
524
- // XXX: Is this right? --pcw
525
- let new_args;
526
- match args {
527
- Some ( args) => new_args = args,
528
- None => new_args = vec:: from_elem ( arity, wild ( ) )
529
- }
530
- Some ( vec:: append ( new_args, vec:: tail ( r) ) )
531
- }
532
- _ => None
533
- }
534
- }
535
- pat_rec( flds, _) => {
536
- let ty_flds = match /*bad*/ copy ty:: get ( left_ty) . sty {
537
- ty:: ty_rec( flds) => flds,
538
- _ => fail ~"bad type for pat_rec"
539
- } ;
540
- let args = vec:: map( ty_flds, |ty_fld| {
541
- match vec:: find ( flds, |f| f. ident == ty_fld. ident ) {
542
- Some ( f) => f. pat ,
543
- _ => wild ( )
544
517
}
545
- } ) ;
546
- Some ( vec:: append( args, vec:: tail( r) ) )
547
- }
548
- pat_struct( _, flds, _) => {
549
- // Is this a struct or an enum variant?
550
- match cx. tcx . def_map . get ( r0. id ) {
551
- def_variant( _, variant_id) => {
552
- if variant ( variant_id) == ctor_id {
553
- // XXX: Is this right? --pcw
554
- let args = flds. map ( |ty_field| {
555
- match vec:: find ( flds, |f| f. ident == ty_field. ident ) {
556
- Some ( f) => f. pat ,
557
- _ => wild ( )
518
+ pat_enum( _, args) => {
519
+ match cx. tcx . def_map . get ( pat_id) {
520
+ def_variant( _, id) if variant ( id) == ctor_id => {
521
+ let args = match args {
522
+ Some ( args) => args,
523
+ None => vec:: from_elem ( arity, wild ( ) )
524
+ } ;
525
+ Some ( vec:: append ( args, vec:: tail ( r) ) )
526
+ }
527
+ def_variant( _, _) => None ,
528
+ def_struct( * ) => {
529
+ // XXX: Is this right? --pcw
530
+ let new_args;
531
+ match args {
532
+ Some ( args) => new_args = args,
533
+ None => new_args = vec:: from_elem ( arity, wild ( ) )
558
534
}
559
- } ) ;
560
- Some ( vec:: append ( args, vec:: tail ( r) ) )
561
- } else {
562
- None
535
+ Some ( vec:: append ( new_args, vec:: tail ( r) ) )
536
+ }
537
+ _ => None
563
538
}
564
539
}
565
- _ => {
566
- // Grab the class data that we care about.
567
- let class_fields, class_id;
568
- match ty:: get ( left_ty) . sty {
569
- ty:: ty_struct( cid, _) => {
570
- class_id = cid;
571
- class_fields = ty:: lookup_struct_fields ( cx. tcx ,
572
- class_id) ;
540
+ pat_rec( ref flds, _) => {
541
+ let ty_flds = match /*bad*/ copy ty:: get ( left_ty) . sty {
542
+ ty:: ty_rec( flds) => flds,
543
+ _ => fail ~"bad type for pat_rec"
544
+ } ;
545
+ let args = vec:: map( ty_flds, |ty_fld| {
546
+ match flds. find ( |f| f. ident == ty_fld. ident ) {
547
+ Some ( f) => f. pat ,
548
+ _ => wild ( )
549
+ }
550
+ } ) ;
551
+ Some ( vec:: append( args, vec:: tail( r) ) )
552
+ }
553
+ pat_struct( _, ref flds, _) => {
554
+ // Is this a struct or an enum variant?
555
+ match cx. tcx . def_map . get ( pat_id) {
556
+ def_variant( _, variant_id) => {
557
+ if variant ( variant_id) == ctor_id {
558
+ // XXX: Is this right? --pcw
559
+ let args = flds. map ( |ty_field| {
560
+ match flds. find ( |f|
561
+ f. ident == ty_field. ident ) {
562
+ Some ( f) => f. pat ,
563
+ _ => wild ( )
564
+ }
565
+ } ) ;
566
+ Some ( vec:: append ( args, vec:: tail ( r) ) )
567
+ } else {
568
+ None
569
+ }
573
570
}
574
571
_ => {
575
- cx. tcx . sess . span_bug ( r0. span , ~"struct pattern \
576
- didn' t resolve to a \
577
- struct ") ;
572
+ // Grab the class data that we care about.
573
+ let class_fields, class_id;
574
+ match ty:: get ( left_ty) . sty {
575
+ ty:: ty_struct( cid, _) => {
576
+ class_id = cid;
577
+ class_fields =
578
+ ty:: lookup_struct_fields ( cx. tcx ,
579
+ class_id) ;
580
+ }
581
+ _ => {
582
+ cx. tcx . sess . span_bug ( pat_span,
583
+ ~"struct pattern didn' t resolve to a struct ") ;
584
+ }
585
+ }
586
+ let args = vec:: map ( class_fields, |class_field| {
587
+ match flds. find ( |f|
588
+ f. ident == class_field. ident ) {
589
+ Some ( f) => f. pat ,
590
+ _ => wild ( )
591
+ }
592
+ } ) ;
593
+ Some ( vec:: append ( args, vec:: tail ( r) ) )
578
594
}
579
595
}
580
- let args = vec:: map ( class_fields, |class_field| {
581
- match vec:: find ( flds, |f| f. ident == class_field. ident ) {
582
- Some ( f) => f. pat ,
583
- _ => wild ( )
596
+ }
597
+ pat_tup( args) => Some ( vec:: append ( args, vec:: tail ( r) ) ) ,
598
+ pat_box( a) | pat_uniq( a) | pat_region( a) =>
599
+ Some ( vec:: append ( ~[ a] , vec:: tail ( r) ) ) ,
600
+ pat_lit( expr) => {
601
+ let e_v = eval_const_expr ( cx. tcx , expr) ;
602
+ let match_ = match ctor_id {
603
+ val( ref v) => compare_const_vals ( e_v, ( * v) ) == 0 ,
604
+ range( ref c_lo, ref c_hi) => {
605
+ compare_const_vals ( ( * c_lo) , e_v) >= 0 &&
606
+ compare_const_vals ( ( * c_hi) , e_v) <= 0
584
607
}
585
- } ) ;
586
- Some ( vec:: append ( args, vec:: tail ( r) ) )
608
+ single => true ,
609
+ _ => fail ~"type error"
610
+ } ;
611
+ if match_ { Some ( vec:: tail ( r) ) } else { None }
587
612
}
588
- }
589
- }
590
- pat_tup( args) => Some ( vec:: append ( args, vec:: tail ( r) ) ) ,
591
- pat_box( a) | pat_uniq( a) | pat_region( a) =>
592
- Some ( vec:: append ( ~[ a] , vec:: tail ( r) ) ) ,
593
- pat_lit( expr) => {
594
- let e_v = eval_const_expr ( cx. tcx , expr) ;
595
- let match_ = match ctor_id {
596
- val( ref v) => compare_const_vals ( e_v, ( * v) ) == 0 ,
597
- range( ref c_lo, ref c_hi) => {
598
- compare_const_vals ( ( * c_lo) , e_v) >= 0 &&
599
- compare_const_vals ( ( * c_hi) , e_v) <= 0
600
- }
601
- single => true ,
602
- _ => fail ~"type error"
603
- } ;
604
- if match_ { Some ( vec:: tail ( r) ) } else { None }
605
- }
606
- pat_range( lo, hi) => {
607
- let ( c_lo, c_hi) = match ctor_id {
608
- val( ref v) => ( ( /*bad*/ copy * v) , ( /*bad*/ copy * v) ) ,
609
- range( ref lo, ref hi) => ( ( /*bad*/ copy * lo) , ( /*bad*/ copy * hi) ) ,
610
- single => return Some ( vec:: tail ( r) ) ,
611
- _ => fail ~"type error"
612
- } ;
613
- let v_lo = eval_const_expr ( cx. tcx , lo) ,
614
- v_hi = eval_const_expr ( cx. tcx , hi) ;
615
- let match_ = compare_const_vals ( c_lo, v_lo) >= 0 &&
613
+ pat_range( lo, hi) => {
614
+ let ( c_lo, c_hi) = match ctor_id {
615
+ val( ref v) => ( ( /*bad*/ copy * v) , ( /*bad*/ copy * v) ) ,
616
+ range( ref lo, ref hi) =>
617
+ ( ( /*bad*/ copy * lo) , ( /*bad*/ copy * hi) ) ,
618
+ single => return Some ( vec:: tail ( r) ) ,
619
+ _ => fail ~"type error"
620
+ } ;
621
+ let v_lo = eval_const_expr ( cx. tcx , lo) ,
622
+ v_hi = eval_const_expr ( cx. tcx , hi) ;
623
+ let match_ = compare_const_vals ( c_lo, v_lo) >= 0 &&
616
624
compare_const_vals ( c_hi, v_hi) <= 0 ;
617
- if match_ { Some ( vec:: tail ( r) ) } else { None }
625
+ if match_ { Some ( vec:: tail ( r) ) } else { None }
618
626
}
619
- pat_vec( elems, tail) => {
620
- match ctor_id {
621
- vec( _) => {
622
- if elems. len ( ) < arity && tail. is_some ( ) {
623
- // XXX: Bad copy.
624
- Some ( vec:: append (
625
- vec:: append ( copy elems, vec:: from_elem (
626
- arity - elems. len ( ) , wild ( )
627
- ) ) ,
628
- vec:: tail ( r)
629
- ) )
630
- } else if elems. len ( ) == arity {
631
- Some ( vec:: append ( elems, vec:: tail ( r) ) )
632
- } else {
633
- None
627
+ pat_vec( elems, tail) => {
628
+ match ctor_id {
629
+ vec( _) => {
630
+ let num_elements = elems. len ( ) ;
631
+ if num_elements < arity && tail. is_some ( ) {
632
+ Some ( vec:: append (
633
+ vec:: append ( elems, vec:: from_elem (
634
+ arity - num_elements, wild ( )
635
+ ) ) ,
636
+ vec:: tail ( r)
637
+ ) )
638
+ } else if num_elements == arity {
639
+ Some ( vec:: append ( elems, vec:: tail ( r) ) )
640
+ } else {
641
+ None
642
+ }
643
+ }
644
+ _ => None
645
+ }
634
646
}
635
- }
636
- _ => None
637
647
}
638
- }
639
648
}
640
649
}
641
650
0 commit comments