@@ -259,14 +259,14 @@ pub enum SubstructureFields<'self> {
259
259
fields: `(field ident, self, [others])`, where the field ident is
260
260
only non-`None` in the case of a struct variant.
261
261
*/
262
- EnumMatching ( uint , ast:: variant , ~[ ( Option < ident > , @expr, ~[ @expr] ) ] ) ,
262
+ EnumMatching ( uint , & ' self ast:: variant , ~[ ( Option < ident > , @expr, ~[ @expr] ) ] ) ,
263
263
264
264
/**
265
265
non-matching variants of the enum, [(variant index, ast::variant,
266
266
[field ident, fields])] (i.e. all fields for self are in the
267
267
first tuple, for other1 are in the second tuple, etc.)
268
268
*/
269
- EnumNonMatching ( ~ [ ( uint, ast:: variant, ~[ ( Option < ident > , @expr) ] ) ] ) ,
269
+ EnumNonMatching ( & ' self [ ( uint , ast:: variant , ~[ ( Option < ident > , @expr) ] ) ] ) ,
270
270
271
271
/// A static method where Self is a struct
272
272
StaticStruct ( & ' self ast:: struct_def , Either < uint , ~[ ident ] > ) ,
@@ -290,7 +290,7 @@ representing each variant: (variant index, ast::variant instance,
290
290
*/
291
291
pub type EnumNonMatchFunc <' self> =
292
292
& ' self fn( @ext_ctxt, span,
293
- ~ [ ( uint, ast:: variant,
293
+ & [ ( uint, ast:: variant,
294
294
~[ ( Option <ident>, @expr) ] ) ] ,
295
295
& [ @expr] ) -> @expr;
296
296
@@ -416,8 +416,9 @@ impl<'self> MethodDef<'self> {
416
416
let mut nonstatic = false ;
417
417
418
418
match self . self_ty {
419
- Some ( self_ptr) => {
420
- let ( self_expr, self_ty) = ty:: get_explicit_self ( cx, span, self_ptr) ;
419
+ Some ( ref self_ptr) => {
420
+ let ( self_expr, self_ty) = ty:: get_explicit_self ( cx, span,
421
+ self_ptr) ;
421
422
422
423
ast_self_ty = self_ty;
423
424
self_args. push ( self_expr) ;
@@ -616,9 +617,10 @@ impl<'self> MethodDef<'self> {
616
617
self_args: & [ @expr] ,
617
618
nonself_args: & [ @expr] )
618
619
-> @expr {
620
+ let mut matches = ~[ ] ;
619
621
self . build_enum_match ( cx, span, enum_def, type_ident,
620
622
self_args, nonself_args,
621
- None , ~ [ ] , 0 )
623
+ None , & mut matches , 0 )
622
624
}
623
625
624
626
@@ -650,58 +652,57 @@ impl<'self> MethodDef<'self> {
650
652
self_args: & [ @expr] ,
651
653
nonself_args: & [ @expr] ,
652
654
matching: Option <uint>,
653
- matches_so_far: ~[ ( uint, ast:: variant,
654
- ~[ ( Option <ident>, @expr) ] ) ] ,
655
+ matches_so_far: & mut ~[ ( uint, ast:: variant,
656
+ ~[ ( Option <ident>, @expr) ] ) ] ,
655
657
match_count: uint) -> @expr {
656
658
if match_count == self_args. len ( ) {
657
659
// we've matched against all arguments, so make the final
658
660
// expression at the bottom of the match tree
659
- match matches_so_far {
660
- [ ] => cx. span_bug ( span, ~"no self match on an enum in generic `deriving`") ,
661
- _ => {
662
- // we currently have a vec of vecs, where each
663
- // subvec is the fields of one of the arguments,
664
- // but if the variants all match, we want this as
665
- // vec of tuples, where each tuple represents a
666
- // field.
667
-
668
- let substructure;
669
-
670
- // most arms don't have matching variants, so do a
671
- // quick check to see if they match (even though
672
- // this means iterating twice) instead of being
673
- // optimistic and doing a pile of allocations etc.
674
- match matching {
675
- Some ( variant_index) => {
676
- // `ref` inside let matches is buggy. Causes havoc wih rusc.
677
- // let (variant_index, ref self_vec) = matches_so_far[0];
678
- let ( variant, self_vec) = match matches_so_far[ 0 ] {
679
- ( _, v, ref s) => ( v, s)
680
- } ;
681
-
682
- let mut enum_matching_fields = vec:: from_elem ( self_vec. len ( ) , ~[ ] ) ;
683
-
684
- for matches_so_far. tail( ) . each |& ( _, _, other_fields) | {
685
- for other_fields. eachi |i, & ( _, other_field) | {
686
- enum_matching_fields[ i] . push ( other_field) ;
687
- }
688
- }
689
- let field_tuples =
690
- do vec:: map_zip( * self_vec,
691
- enum_matching_fields) |& ( id, self_f) , & other| {
692
- ( id, self_f, other)
693
- } ;
694
- substructure = EnumMatching ( variant_index, variant, field_tuples) ;
695
- }
696
- None => {
697
- substructure = EnumNonMatching ( matches_so_far) ;
661
+ if matches_so_far. len ( ) == 0 {
662
+ cx. span_bug ( span, ~"no self match on an enum in generic \
663
+ `deriving`") ;
664
+ }
665
+ // we currently have a vec of vecs, where each
666
+ // subvec is the fields of one of the arguments,
667
+ // but if the variants all match, we want this as
668
+ // vec of tuples, where each tuple represents a
669
+ // field.
670
+
671
+ let substructure;
672
+
673
+ // most arms don't have matching variants, so do a
674
+ // quick check to see if they match (even though
675
+ // this means iterating twice) instead of being
676
+ // optimistic and doing a pile of allocations etc.
677
+ match matching {
678
+ Some ( variant_index) => {
679
+ // `ref` inside let matches is buggy. Causes havoc wih rusc.
680
+ // let (variant_index, ref self_vec) = matches_so_far[0];
681
+ let ( variant, self_vec) = match matches_so_far[ 0 ] {
682
+ ( _, ref v, ref s) => ( v, s)
683
+ } ;
684
+
685
+ let mut enum_matching_fields = vec:: from_elem ( self_vec. len ( ) , ~[ ] ) ;
686
+
687
+ for matches_so_far. tail( ) . each |& ( _, _, other_fields) | {
688
+ for other_fields. eachi |i, & ( _, other_field) | {
689
+ enum_matching_fields[ i] . push ( other_field) ;
698
690
}
699
691
}
700
- self . call_substructure_method( cx, span, type_ident,
701
- self_args, nonself_args,
702
- & substructure)
692
+ let field_tuples =
693
+ do vec:: map_zip( * self_vec,
694
+ enum_matching_fields) |& ( id, self_f) , & other| {
695
+ ( id, self_f, other)
696
+ } ;
697
+ substructure = EnumMatching ( variant_index, variant, field_tuples) ;
698
+ }
699
+ None => {
700
+ substructure = EnumNonMatching ( * matches_so_far) ;
703
701
}
704
702
}
703
+ self . call_substructure_method( cx, span, type_ident,
704
+ self_args, nonself_args,
705
+ & substructure)
705
706
706
707
} else { // there are still matches to create
707
708
let current_match_str = if match_count == 0 {
@@ -712,9 +713,6 @@ impl<'self> MethodDef<'self> {
712
713
713
714
let mut arms = ~[ ] ;
714
715
715
- // this is used as a stack
716
- let mut matches_so_far = matches_so_far;
717
-
718
716
// the code for nonmatching variants only matters when
719
717
// we've seen at least one other variant already
720
718
if self . const_nonmatching && match_count > 0 {
@@ -732,7 +730,7 @@ impl<'self> MethodDef<'self> {
732
730
current_match_str,
733
731
ast:: m_imm) ;
734
732
735
- matches_so_far. push ( ( index, * variant, idents) ) ;
733
+ matches_so_far. push ( ( index, /*bad*/ copy * variant, idents) ) ;
736
734
let arm_expr = self . build_enum_match ( cx, span,
737
735
enum_def,
738
736
type_ident,
@@ -744,9 +742,10 @@ impl<'self> MethodDef<'self> {
744
742
arms. push ( build:: mk_arm ( cx, span, ~[ pattern ] , arm_expr) ) ;
745
743
746
744
if enum_def. variants . len ( ) > 1 {
745
+ let e = & EnumNonMatching ( & [ ] ) ;
747
746
let wild_expr = self . call_substructure_method ( cx, span, type_ident,
748
747
self_args, nonself_args,
749
- & EnumNonMatching ( ~ [ ] ) ) ;
748
+ e ) ;
750
749
let wild_arm = build:: mk_arm ( cx, span,
751
750
~[ build:: mk_pat_wild ( cx, span) ] ,
752
751
wild_expr) ;
@@ -760,7 +759,7 @@ impl<'self> MethodDef<'self> {
760
759
current_match_str,
761
760
ast:: m_imm) ;
762
761
763
- matches_so_far. push ( ( index, * variant, idents) ) ;
762
+ matches_so_far. push ( ( index, /*bad*/ copy * variant, idents) ) ;
764
763
let new_matching =
765
764
match matching {
766
765
_ if match_count == 0 => Some ( index) ,
@@ -850,7 +849,7 @@ pub fn cs_fold(use_foldl: bool,
850
849
cx : @ext_ctxt , span : span ,
851
850
substructure : & Substructure ) -> @expr {
852
851
match * substructure. fields {
853
- EnumMatching ( _, _, all_fields) | Struct ( all_fields) => {
852
+ EnumMatching ( _, _, ref all_fields) | Struct ( ref all_fields) => {
854
853
if use_foldl {
855
854
do all_fields. foldl ( base) |& old, & ( _, self_f, other_fs) | {
856
855
f ( cx, span, old, self_f, other_fs)
@@ -861,8 +860,9 @@ pub fn cs_fold(use_foldl: bool,
861
860
}
862
861
}
863
862
} ,
864
- EnumNonMatching ( all_enums) => enum_nonmatch_f ( cx, span,
865
- all_enums, substructure. nonself_args ) ,
863
+ EnumNonMatching ( ref all_enums) => enum_nonmatch_f( cx, span,
864
+ * all_enums,
865
+ substructure. nonself_args ) ,
866
866
StaticEnum ( * ) | StaticStruct ( * ) => {
867
867
cx. span_bug ( span, "Static function in `deriving`" )
868
868
}
@@ -885,7 +885,7 @@ pub fn cs_same_method(f: &fn(@ext_ctxt, span, ~[@expr]) -> @expr,
885
885
cx : @ext_ctxt , span : span ,
886
886
substructure : & Substructure ) -> @expr {
887
887
match * substructure. fields {
888
- EnumMatching ( _, _, all_fields) | Struct ( all_fields) => {
888
+ EnumMatching ( _, _, ref all_fields) | Struct ( ref all_fields) => {
889
889
// call self_n.method(other_1_n, other_2_n, ...)
890
890
let called = do all_fields. map |& ( _, self_field, other_fields) | {
891
891
build:: mk_method_call ( cx, span,
@@ -896,8 +896,9 @@ pub fn cs_same_method(f: &fn(@ext_ctxt, span, ~[@expr]) -> @expr,
896
896
897
897
f ( cx, span, called)
898
898
} ,
899
- EnumNonMatching ( all_enums) => enum_nonmatch_f ( cx, span,
900
- all_enums, substructure. nonself_args ) ,
899
+ EnumNonMatching ( ref all_enums) => enum_nonmatch_f ( cx, span,
900
+ * all_enums,
901
+ substructure. nonself_args ) ,
901
902
StaticEnum ( * ) | StaticStruct ( * ) => {
902
903
cx. span_bug ( span, "Static function in `deriving`" )
903
904
}
0 commit comments