@@ -114,7 +114,7 @@ pub trait Folder {
114114 noop_fold_type_method ( m, self )
115115 }
116116
117- fn fold_method ( & mut self , m : Gc < Method > ) -> Gc < Method > {
117+ fn fold_method ( & mut self , m : Gc < Method > ) -> SmallVector < Gc < Method > > {
118118 noop_fold_method ( & * m, self )
119119 }
120120
@@ -465,10 +465,16 @@ fn fold_interpolated<T: Folder>(nt : &token::Nonterminal, fld: &mut T) -> token:
465465 match * nt {
466466 token:: NtItem ( item) =>
467467 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
468471 . expect_one ( "expected fold to produce exactly one item" ) ) ,
469472 token:: NtBlock ( block) => token:: NtBlock ( fld. fold_block ( block) ) ,
470473 token:: NtStmt ( stmt) =>
471474 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
472478 . expect_one ( "expected fold to produce exactly one statement" ) ) ,
473479 token:: NtPat ( pat) => token:: NtPat ( fld. fold_pat ( pat) ) ,
474480 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_
683689 ItemImpl ( fold_generics ( generics, folder) ,
684690 ifce. as_ref ( ) . map ( |p| fold_trait_ref ( p, folder) ) ,
685691 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 ( )
687693 )
688694 }
689695 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
695712 } ) . collect ( ) ;
696713 ItemTrait ( fold_generics ( generics, folder) ,
697714 unbound. clone ( ) ,
@@ -791,9 +808,11 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem,
791808 }
792809}
793810
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 > > {
795814 let id = folder. new_id ( m. id ) ; // Needs to be first, for ast_map.
796- box ( GC ) Method {
815+ SmallVector :: one ( box ( GC ) Method {
797816 attrs : m. attrs . iter ( ) . map ( |a| folder. fold_attribute ( * a) ) . collect ( ) ,
798817 id : id,
799818 span : folder. new_span ( m. span ) ,
@@ -809,7 +828,7 @@ pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> Gc<Method> {
809828 } ,
810829 MethMac ( ref mac) => MethMac ( folder. fold_mac ( mac) ) ,
811830 }
812- }
831+ } )
813832}
814833
815834pub fn noop_fold_pat < T : Folder > ( p : Gc < Pat > , folder : & mut T ) -> Gc < Pat > {
0 commit comments