@@ -114,7 +114,7 @@ pub trait Folder {
114
114
noop_fold_type_method ( m, self )
115
115
}
116
116
117
- fn fold_method ( & mut self , m : Gc < Method > ) -> Gc < Method > {
117
+ fn fold_method ( & mut self , m : Gc < Method > ) -> SmallVector < Gc < Method > > {
118
118
noop_fold_method ( & * m, self )
119
119
}
120
120
@@ -465,10 +465,16 @@ fn fold_interpolated<T: Folder>(nt : &token::Nonterminal, fld: &mut T) -> token:
465
465
match * nt {
466
466
token:: NtItem ( item) =>
467
467
token:: NtItem ( fld. fold_item ( item)
468
+ // this is probably okay, because the only folds likely
469
+ // to peek inside interpolated nodes will be renamings/markings,
470
+ // which map single items to single items
468
471
. expect_one ( "expected fold to produce exactly one item" ) ) ,
469
472
token:: NtBlock ( block) => token:: NtBlock ( fld. fold_block ( block) ) ,
470
473
token:: NtStmt ( stmt) =>
471
474
token:: NtStmt ( fld. fold_stmt ( stmt)
475
+ // this is probably okay, because the only folds likely
476
+ // to peek inside interpolated nodes will be renamings/markings,
477
+ // which map single items to single items
472
478
. expect_one ( "expected fold to produce exactly one statement" ) ) ,
473
479
token:: NtPat ( pat) => token:: NtPat ( fld. fold_pat ( pat) ) ,
474
480
token:: NtExpr ( expr) => token:: NtExpr ( fld. fold_expr ( expr) ) ,
@@ -683,15 +689,26 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
683
689
ItemImpl ( fold_generics ( generics, folder) ,
684
690
ifce. as_ref ( ) . map ( |p| fold_trait_ref ( p, folder) ) ,
685
691
folder. fold_ty ( ty) ,
686
- methods. iter ( ) . map ( |x| folder. fold_method ( * x) ) . collect ( )
692
+ methods. iter ( ) . flat_map ( |x| folder. fold_method ( * x) . move_iter ( ) ) . collect ( )
687
693
)
688
694
}
689
695
ItemTrait ( ref generics, ref unbound, ref traits, ref methods) => {
690
- let methods = methods. iter ( ) . map ( |method| {
691
- match * method {
692
- Required ( ref m) => Required ( folder. fold_type_method ( m) ) ,
693
- Provided ( method) => Provided ( folder. fold_method ( method) )
694
- }
696
+ let methods = methods. iter ( ) . flat_map ( |method| {
697
+ let r = match * method {
698
+ Required ( ref m) =>
699
+ SmallVector :: one ( Required ( folder. fold_type_method ( m) ) ) . move_iter ( ) ,
700
+ Provided ( method) => {
701
+ // the awkward collect/iter idiom here is because
702
+ // even though an iter and a map satisfy the same trait bound,
703
+ // they're not actually the same type, so the method arms
704
+ // don't unify.
705
+ let methods : SmallVector < ast:: TraitMethod > =
706
+ folder. fold_method ( method) . move_iter ( )
707
+ . map ( |m| Provided ( m) ) . collect ( ) ;
708
+ methods. move_iter ( )
709
+ }
710
+ } ;
711
+ r
695
712
} ) . collect ( ) ;
696
713
ItemTrait ( fold_generics ( generics, folder) ,
697
714
unbound. clone ( ) ,
@@ -791,9 +808,11 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem,
791
808
}
792
809
}
793
810
794
- pub fn noop_fold_method < T : Folder > ( m : & Method , folder : & mut T ) -> Gc < Method > {
811
+ // Default fold over a method.
812
+ // Invariant: produces exactly one method.
813
+ pub fn noop_fold_method < T : Folder > ( m : & Method , folder : & mut T ) -> SmallVector < Gc < Method > > {
795
814
let id = folder. new_id ( m. id ) ; // Needs to be first, for ast_map.
796
- box ( GC ) Method {
815
+ SmallVector :: one ( box ( GC ) Method {
797
816
attrs : m. attrs . iter ( ) . map ( |a| folder. fold_attribute ( * a) ) . collect ( ) ,
798
817
id : id,
799
818
span : folder. new_span ( m. span ) ,
@@ -809,7 +828,7 @@ pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> Gc<Method> {
809
828
} ,
810
829
MethMac ( ref mac) => MethMac ( folder. fold_mac ( mac) ) ,
811
830
}
812
- }
831
+ } )
813
832
}
814
833
815
834
pub fn noop_fold_pat < T : Folder > ( p : Gc < Pat > , folder : & mut T ) -> Gc < Pat > {
0 commit comments