update fold_method to return a smallvector
This is nice for macros, to allow them to expand into multiple methods
This commit is contained in:
@@ -114,7 +114,7 @@ pub trait Folder {
|
||||
noop_fold_type_method(m, self)
|
||||
}
|
||||
|
||||
fn fold_method(&mut self, m: Gc<Method>) -> Gc<Method> {
|
||||
fn fold_method(&mut self, m: Gc<Method>) -> SmallVector<Gc<Method>> {
|
||||
noop_fold_method(&*m, self)
|
||||
}
|
||||
|
||||
@@ -465,10 +465,16 @@ fn fold_interpolated<T: Folder>(nt : &token::Nonterminal, fld: &mut T) -> token:
|
||||
match *nt {
|
||||
token::NtItem(item) =>
|
||||
token::NtItem(fld.fold_item(item)
|
||||
// this is probably okay, because the only folds likely
|
||||
// to peek inside interpolated nodes will be renamings/markings,
|
||||
// which map single items to single items
|
||||
.expect_one("expected fold to produce exactly one item")),
|
||||
token::NtBlock(block) => token::NtBlock(fld.fold_block(block)),
|
||||
token::NtStmt(stmt) =>
|
||||
token::NtStmt(fld.fold_stmt(stmt)
|
||||
// this is probably okay, because the only folds likely
|
||||
// to peek inside interpolated nodes will be renamings/markings,
|
||||
// which map single items to single items
|
||||
.expect_one("expected fold to produce exactly one statement")),
|
||||
token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)),
|
||||
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_
|
||||
ItemImpl(fold_generics(generics, folder),
|
||||
ifce.as_ref().map(|p| fold_trait_ref(p, folder)),
|
||||
folder.fold_ty(ty),
|
||||
methods.iter().map(|x| folder.fold_method(*x)).collect()
|
||||
methods.iter().flat_map(|x| folder.fold_method(*x).move_iter()).collect()
|
||||
)
|
||||
}
|
||||
ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
|
||||
let methods = methods.iter().map(|method| {
|
||||
match *method {
|
||||
Required(ref m) => Required(folder.fold_type_method(m)),
|
||||
Provided(method) => Provided(folder.fold_method(method))
|
||||
}
|
||||
let methods = methods.iter().flat_map(|method| {
|
||||
let r = match *method {
|
||||
Required(ref m) =>
|
||||
SmallVector::one(Required(folder.fold_type_method(m))).move_iter(),
|
||||
Provided(method) => {
|
||||
// the awkward collect/iter idiom here is because
|
||||
// even though an iter and a map satisfy the same trait bound,
|
||||
// they're not actually the same type, so the method arms
|
||||
// don't unify.
|
||||
let methods : SmallVector<ast::TraitMethod> =
|
||||
folder.fold_method(method).move_iter()
|
||||
.map(|m| Provided(m)).collect();
|
||||
methods.move_iter()
|
||||
}
|
||||
};
|
||||
r
|
||||
}).collect();
|
||||
ItemTrait(fold_generics(generics, folder),
|
||||
unbound.clone(),
|
||||
@@ -791,9 +808,11 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> Gc<Method> {
|
||||
// Default fold over a method.
|
||||
// Invariant: produces exactly one method.
|
||||
pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> SmallVector<Gc<Method>> {
|
||||
let id = folder.new_id(m.id); // Needs to be first, for ast_map.
|
||||
box(GC) Method {
|
||||
SmallVector::one(box(GC) Method {
|
||||
attrs: m.attrs.iter().map(|a| folder.fold_attribute(*a)).collect(),
|
||||
id: id,
|
||||
span: folder.new_span(m.span),
|
||||
@@ -809,7 +828,7 @@ pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> Gc<Method> {
|
||||
},
|
||||
MethMac(ref mac) => MethMac(folder.fold_mac(mac)),
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn noop_fold_pat<T: Folder>(p: Gc<Pat>, folder: &mut T) -> Gc<Pat> {
|
||||
|
||||
Reference in New Issue
Block a user