libsyntax: use unboxed closures
This commit is contained in:
parent
2160427900
commit
0dac05dd62
32 changed files with 377 additions and 245 deletions
|
@ -181,22 +181,23 @@ impl<'a> FnLikeNode<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kind(self) -> visit::FnKind<'a> {
|
pub fn kind(self) -> visit::FnKind<'a> {
|
||||||
let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> {
|
let item = |: p: ItemFnParts<'a>| -> visit::FnKind<'a> {
|
||||||
visit::FkItemFn(p.ident, p.generics, p.style, p.abi)
|
visit::FkItemFn(p.ident, p.generics, p.style, p.abi)
|
||||||
};
|
};
|
||||||
let closure = |_: ClosureParts| {
|
let closure = |: _: ClosureParts| {
|
||||||
visit::FkFnBlock
|
visit::FkFnBlock
|
||||||
};
|
};
|
||||||
let method = |m: &'a ast::Method| {
|
let method = |: m: &'a ast::Method| {
|
||||||
visit::FkMethod(m.pe_ident(), m.pe_generics(), m)
|
visit::FkMethod(m.pe_ident(), m.pe_generics(), m)
|
||||||
};
|
};
|
||||||
self.handle(item, method, closure)
|
self.handle(item, method, closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle<A>(self,
|
fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
|
||||||
item_fn: |ItemFnParts<'a>| -> A,
|
I: FnOnce(ItemFnParts<'a>) -> A,
|
||||||
method: |&'a ast::Method| -> A,
|
M: FnOnce(&'a ast::Method) -> A,
|
||||||
closure: |ClosureParts<'a>| -> A) -> A {
|
C: FnOnce(ClosureParts<'a>) -> A,
|
||||||
|
{
|
||||||
match self.node {
|
match self.node {
|
||||||
ast_map::NodeItem(i) => match i.node {
|
ast_map::NodeItem(i) => match i.node {
|
||||||
ast::ItemFn(ref decl, style, abi, ref generics, ref block) =>
|
ast::ItemFn(ref decl, style, abi, ref generics, ref block) =>
|
||||||
|
|
|
@ -424,7 +424,9 @@ impl<'ast> Map<'ast> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_path<T>(&self, id: NodeId, f: |PathElems| -> T) -> T {
|
pub fn with_path<T, F>(&self, id: NodeId, f: F) -> T where
|
||||||
|
F: FnOnce(PathElems) -> T,
|
||||||
|
{
|
||||||
self.with_path_next(id, None, f)
|
self.with_path_next(id, None, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +440,9 @@ impl<'ast> Map<'ast> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_path_next<T>(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -> T {
|
fn with_path_next<T, F>(&self, id: NodeId, next: LinkedPath, f: F) -> T where
|
||||||
|
F: FnOnce(PathElems) -> T,
|
||||||
|
{
|
||||||
let parent = self.get_parent(id);
|
let parent = self.get_parent(id);
|
||||||
let parent = match self.find_entry(id) {
|
let parent = match self.find_entry(id) {
|
||||||
Some(EntryForeignItem(..)) | Some(EntryVariant(..)) => {
|
Some(EntryForeignItem(..)) | Some(EntryVariant(..)) => {
|
||||||
|
@ -470,7 +474,9 @@ impl<'ast> Map<'ast> {
|
||||||
|
|
||||||
/// Given a node ID and a closure, apply the closure to the array
|
/// Given a node ID and a closure, apply the closure to the array
|
||||||
/// of attributes associated with the AST corresponding to the Node ID
|
/// of attributes associated with the AST corresponding to the Node ID
|
||||||
pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
|
pub fn with_attrs<T, F>(&self, id: NodeId, f: F) -> T where
|
||||||
|
F: FnOnce(Option<&[Attribute]>) -> T,
|
||||||
|
{
|
||||||
let attrs = match self.get(id) {
|
let attrs = match self.get(id) {
|
||||||
NodeItem(i) => Some(i.attrs.as_slice()),
|
NodeItem(i) => Some(i.attrs.as_slice()),
|
||||||
NodeForeignItem(fi) => Some(fi.attrs.as_slice()),
|
NodeForeignItem(fi) => Some(fi.attrs.as_slice()),
|
||||||
|
|
|
@ -602,6 +602,7 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind,
|
||||||
id_visitor.operation.result
|
id_visitor.operation.result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(#19596) unbox `it`
|
||||||
pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
|
pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
|
||||||
if !it(pat) {
|
if !it(pat) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -632,21 +633,21 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EachViewItem {
|
pub trait EachViewItem {
|
||||||
fn each_view_item(&self, f: |&ast::ViewItem| -> bool) -> bool;
|
fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EachViewItemData<'a> {
|
struct EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
|
||||||
callback: |&ast::ViewItem|: 'a -> bool,
|
callback: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'v> Visitor<'v> for EachViewItemData<'a> {
|
impl<'v, F> Visitor<'v> for EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
|
||||||
fn visit_view_item(&mut self, view_item: &ast::ViewItem) {
|
fn visit_view_item(&mut self, view_item: &ast::ViewItem) {
|
||||||
let _ = (self.callback)(view_item);
|
let _ = (self.callback)(view_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EachViewItem for ast::Crate {
|
impl EachViewItem for ast::Crate {
|
||||||
fn each_view_item(&self, f: |&ast::ViewItem| -> bool) -> bool {
|
fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool {
|
||||||
let mut visit = EachViewItemData {
|
let mut visit = EachViewItemData {
|
||||||
callback: f,
|
callback: f,
|
||||||
};
|
};
|
||||||
|
|
|
@ -115,7 +115,8 @@ impl AttrMetaMethods for P<MetaItem> {
|
||||||
|
|
||||||
pub trait AttributeMethods {
|
pub trait AttributeMethods {
|
||||||
fn meta<'a>(&'a self) -> &'a MetaItem;
|
fn meta<'a>(&'a self) -> &'a MetaItem;
|
||||||
fn with_desugared_doc<T>(&self, f: |&Attribute| -> T) -> T;
|
fn with_desugared_doc<T, F>(&self, f: F) -> T where
|
||||||
|
F: FnOnce(&Attribute) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AttributeMethods for Attribute {
|
impl AttributeMethods for Attribute {
|
||||||
|
@ -127,7 +128,9 @@ impl AttributeMethods for Attribute {
|
||||||
/// Convert self to a normal #[doc="foo"] comment, if it is a
|
/// Convert self to a normal #[doc="foo"] comment, if it is a
|
||||||
/// comment like `///` or `/** */`. (Returns self unchanged for
|
/// comment like `///` or `/** */`. (Returns self unchanged for
|
||||||
/// non-sugared doc attributes.)
|
/// non-sugared doc attributes.)
|
||||||
fn with_desugared_doc<T>(&self, f: |&Attribute| -> T) -> T {
|
fn with_desugared_doc<T, F>(&self, f: F) -> T where
|
||||||
|
F: FnOnce(&Attribute) -> T,
|
||||||
|
{
|
||||||
if self.node.is_sugared_doc {
|
if self.node.is_sugared_doc {
|
||||||
let comment = self.value_str().unwrap();
|
let comment = self.value_str().unwrap();
|
||||||
let meta = mk_name_value_item_str(
|
let meta = mk_name_value_item_str(
|
||||||
|
|
|
@ -568,7 +568,9 @@ impl CodeMap {
|
||||||
ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1)
|
ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T {
|
pub fn with_expn_info<T, F>(&self, id: ExpnId, f: F) -> T where
|
||||||
|
F: FnOnce(Option<&ExpnInfo>) -> T,
|
||||||
|
{
|
||||||
match id {
|
match id {
|
||||||
NO_EXPANSION => f(None),
|
NO_EXPANSION => f(None),
|
||||||
ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint]))
|
ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint]))
|
||||||
|
|
|
@ -19,8 +19,8 @@ use util::small_vector::SmallVector;
|
||||||
|
|
||||||
/// A folder that strips out items that do not belong in the current
|
/// A folder that strips out items that do not belong in the current
|
||||||
/// configuration.
|
/// configuration.
|
||||||
struct Context<'a> {
|
struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
|
||||||
in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool,
|
in_cfg: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support conditional compilation by transforming the AST, stripping out
|
// Support conditional compilation by transforming the AST, stripping out
|
||||||
|
@ -30,7 +30,7 @@ pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) ->
|
||||||
strip_items(krate, |attrs| in_cfg(diagnostic, config.as_slice(), attrs))
|
strip_items(krate, |attrs| in_cfg(diagnostic, config.as_slice(), attrs))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fold::Folder for Context<'a> {
|
impl<F> fold::Folder for Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
|
||||||
fn fold_mod(&mut self, module: ast::Mod) -> ast::Mod {
|
fn fold_mod(&mut self, module: ast::Mod) -> ast::Mod {
|
||||||
fold_mod(self, module)
|
fold_mod(self, module)
|
||||||
}
|
}
|
||||||
|
@ -54,16 +54,20 @@ impl<'a> fold::Folder for Context<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn strip_items(krate: ast::Crate,
|
pub fn strip_items<F>(krate: ast::Crate, in_cfg: F) -> ast::Crate where
|
||||||
in_cfg: |attrs: &[ast::Attribute]| -> bool)
|
F: FnMut(&[ast::Attribute]) -> bool,
|
||||||
-> ast::Crate {
|
{
|
||||||
let mut ctxt = Context {
|
let mut ctxt = Context {
|
||||||
in_cfg: in_cfg,
|
in_cfg: in_cfg,
|
||||||
};
|
};
|
||||||
ctxt.fold_crate(krate)
|
ctxt.fold_crate(krate)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_view_item(cx: &mut Context, view_item: ast::ViewItem) -> Option<ast::ViewItem> {
|
fn filter_view_item<F>(cx: &mut Context<F>,
|
||||||
|
view_item: ast::ViewItem)
|
||||||
|
-> Option<ast::ViewItem> where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
if view_item_in_cfg(cx, &view_item) {
|
if view_item_in_cfg(cx, &view_item) {
|
||||||
Some(view_item)
|
Some(view_item)
|
||||||
} else {
|
} else {
|
||||||
|
@ -71,7 +75,11 @@ fn filter_view_item(cx: &mut Context, view_item: ast::ViewItem) -> Option<ast::V
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) -> ast::Mod {
|
fn fold_mod<F>(cx: &mut Context<F>,
|
||||||
|
ast::Mod {inner,
|
||||||
|
view_items, items}: ast::Mod) -> ast::Mod where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
ast::Mod {
|
ast::Mod {
|
||||||
inner: inner,
|
inner: inner,
|
||||||
view_items: view_items.into_iter().filter_map(|a| {
|
view_items: view_items.into_iter().filter_map(|a| {
|
||||||
|
@ -83,8 +91,11 @@ fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_foreign_item(cx: &mut Context, item: P<ast::ForeignItem>)
|
fn filter_foreign_item<F>(cx: &mut Context<F>,
|
||||||
-> Option<P<ast::ForeignItem>> {
|
item: P<ast::ForeignItem>)
|
||||||
|
-> Option<P<ast::ForeignItem>> where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
if foreign_item_in_cfg(cx, &*item) {
|
if foreign_item_in_cfg(cx, &*item) {
|
||||||
Some(item)
|
Some(item)
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,8 +103,11 @@ fn filter_foreign_item(cx: &mut Context, item: P<ast::ForeignItem>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}: ast::ForeignMod)
|
fn fold_foreign_mod<F>(cx: &mut Context<F>,
|
||||||
-> ast::ForeignMod {
|
ast::ForeignMod {abi, view_items, items}: ast::ForeignMod)
|
||||||
|
-> ast::ForeignMod where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
ast::ForeignMod {
|
ast::ForeignMod {
|
||||||
abi: abi,
|
abi: abi,
|
||||||
view_items: view_items.into_iter().filter_map(|a| {
|
view_items: view_items.into_iter().filter_map(|a| {
|
||||||
|
@ -105,7 +119,9 @@ fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_item(cx: &mut Context, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
|
fn fold_item<F>(cx: &mut Context<F>, item: P<ast::Item>) -> SmallVector<P<ast::Item>> where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
if item_in_cfg(cx, &*item) {
|
if item_in_cfg(cx, &*item) {
|
||||||
SmallVector::one(item.map(|i| cx.fold_item_simple(i)))
|
SmallVector::one(item.map(|i| cx.fold_item_simple(i)))
|
||||||
} else {
|
} else {
|
||||||
|
@ -113,7 +129,9 @@ fn fold_item(cx: &mut Context, item: P<ast::Item>) -> SmallVector<P<ast::Item>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ {
|
fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_ where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
let item = match item {
|
let item = match item {
|
||||||
ast::ItemImpl(a, b, c, impl_items) => {
|
ast::ItemImpl(a, b, c, impl_items) => {
|
||||||
let impl_items = impl_items.into_iter()
|
let impl_items = impl_items.into_iter()
|
||||||
|
@ -166,7 +184,9 @@ fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ {
|
||||||
fold::noop_fold_item_underscore(item, cx)
|
fold::noop_fold_item_underscore(item, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_struct(cx: &mut Context, def: P<ast::StructDef>) -> P<ast::StructDef> {
|
fn fold_struct<F>(cx: &mut Context<F>, def: P<ast::StructDef>) -> P<ast::StructDef> where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
def.map(|ast::StructDef { fields, ctor_id }| {
|
def.map(|ast::StructDef { fields, ctor_id }| {
|
||||||
ast::StructDef {
|
ast::StructDef {
|
||||||
fields: fields.into_iter().filter(|m| {
|
fields: fields.into_iter().filter(|m| {
|
||||||
|
@ -177,7 +197,9 @@ fn fold_struct(cx: &mut Context, def: P<ast::StructDef>) -> P<ast::StructDef> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn retain_stmt(cx: &mut Context, stmt: &ast::Stmt) -> bool {
|
fn retain_stmt<F>(cx: &mut Context<F>, stmt: &ast::Stmt) -> bool where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
ast::StmtDecl(ref decl, _) => {
|
ast::StmtDecl(ref decl, _) => {
|
||||||
match decl.node {
|
match decl.node {
|
||||||
|
@ -191,7 +213,9 @@ fn retain_stmt(cx: &mut Context, stmt: &ast::Stmt) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_block(cx: &mut Context, b: P<ast::Block>) -> P<ast::Block> {
|
fn fold_block<F>(cx: &mut Context<F>, b: P<ast::Block>) -> P<ast::Block> where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
b.map(|ast::Block {id, view_items, stmts, expr, rules, span}| {
|
b.map(|ast::Block {id, view_items, stmts, expr, rules, span}| {
|
||||||
let resulting_stmts: Vec<P<ast::Stmt>> =
|
let resulting_stmts: Vec<P<ast::Stmt>> =
|
||||||
stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect();
|
stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect();
|
||||||
|
@ -212,7 +236,9 @@ fn fold_block(cx: &mut Context, b: P<ast::Block>) -> P<ast::Block> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_expr(cx: &mut Context, expr: P<ast::Expr>) -> P<ast::Expr> {
|
fn fold_expr<F>(cx: &mut Context<F>, expr: P<ast::Expr>) -> P<ast::Expr> where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
expr.map(|ast::Expr {id, span, node}| {
|
expr.map(|ast::Expr {id, span, node}| {
|
||||||
fold::noop_fold_expr(ast::Expr {
|
fold::noop_fold_expr(ast::Expr {
|
||||||
id: id,
|
id: id,
|
||||||
|
@ -229,19 +255,27 @@ fn fold_expr(cx: &mut Context, expr: P<ast::Expr>) -> P<ast::Expr> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool {
|
fn item_in_cfg<F>(cx: &mut Context<F>, item: &ast::Item) -> bool where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
return (cx.in_cfg)(item.attrs.as_slice());
|
return (cx.in_cfg)(item.attrs.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foreign_item_in_cfg(cx: &mut Context, item: &ast::ForeignItem) -> bool {
|
fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
return (cx.in_cfg)(item.attrs.as_slice());
|
return (cx.in_cfg)(item.attrs.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool {
|
fn view_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ViewItem) -> bool where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
return (cx.in_cfg)(item.attrs.as_slice());
|
return (cx.in_cfg)(item.attrs.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool {
|
fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
match *meth {
|
match *meth {
|
||||||
ast::RequiredMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
|
ast::RequiredMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
|
||||||
ast::ProvidedMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
|
ast::ProvidedMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
|
||||||
|
@ -249,7 +283,9 @@ fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn impl_item_in_cfg(cx: &mut Context, impl_item: &ast::ImplItem) -> bool {
|
fn impl_item_in_cfg<F>(cx: &mut Context<F>, impl_item: &ast::ImplItem) -> bool where
|
||||||
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
|
{
|
||||||
match *impl_item {
|
match *impl_item {
|
||||||
ast::MethodImplItem(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
|
ast::MethodImplItem(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
|
||||||
ast::TypeImplItem(ref typ) => (cx.in_cfg)(typ.attrs.as_slice()),
|
ast::TypeImplItem(ref typ) => (cx.in_cfg)(typ.attrs.as_slice()),
|
||||||
|
|
|
@ -581,7 +581,9 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
|
||||||
cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site))
|
cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect<T>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) -> T {
|
pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where
|
||||||
|
M: FnOnce() -> String,
|
||||||
|
{
|
||||||
match opt {
|
match opt {
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
None => diag.handler().bug(msg().as_slice()),
|
None => diag.handler().bug(msg().as_slice()),
|
||||||
|
|
|
@ -25,14 +25,18 @@ thread_local!(static USED_DIAGNOSTICS: RefCell<HashMap<Name, Span>> = {
|
||||||
RefCell::new(HashMap::new())
|
RefCell::new(HashMap::new())
|
||||||
})
|
})
|
||||||
|
|
||||||
fn with_registered_diagnostics<T>(f: |&mut HashMap<Name, Option<Name>>| -> T) -> T {
|
fn with_registered_diagnostics<T, F>(f: F) -> T where
|
||||||
REGISTERED_DIAGNOSTICS.with(|slot| {
|
F: FnOnce(&mut HashMap<Name, Option<Name>>) -> T,
|
||||||
|
{
|
||||||
|
REGISTERED_DIAGNOSTICS.with(move |slot| {
|
||||||
f(&mut *slot.borrow_mut())
|
f(&mut *slot.borrow_mut())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_used_diagnostics<T>(f: |&mut HashMap<Name, Span>| -> T) -> T {
|
fn with_used_diagnostics<T, F>(f: F) -> T where
|
||||||
USED_DIAGNOSTICS.with(|slot| {
|
F: FnOnce(&mut HashMap<Name, Span>) -> T,
|
||||||
|
{
|
||||||
|
USED_DIAGNOSTICS.with(move |slot| {
|
||||||
f(&mut *slot.borrow_mut())
|
f(&mut *slot.borrow_mut())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,13 @@ use ext::deriving::generic::*;
|
||||||
use ext::deriving::generic::ty::*;
|
use ext::deriving::generic::ty::*;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_bound(cx: &mut ExtCtxt,
|
pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
let name = match mitem.node {
|
let name = match mitem.node {
|
||||||
MetaWord(ref tname) => {
|
MetaWord(ref tname) => {
|
||||||
match tname.get() {
|
match tname.get() {
|
||||||
|
|
|
@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_clone(cx: &mut ExtCtxt,
|
pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||||
let attrs = vec!(cx.attribute(span, inline));
|
let attrs = vec!(cx.attribute(span, inline));
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
|
|
|
@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_eq(cx: &mut ExtCtxt,
|
pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
// structures are equal if all fields are equal, and non equal, if
|
// structures are equal if all fields are equal, and non equal, if
|
||||||
// any fields are not equal or if the enum variants are different
|
// any fields are not equal or if the enum variants are different
|
||||||
fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
|
fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
|
||||||
|
|
|
@ -20,11 +20,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_ord(cx: &mut ExtCtxt,
|
pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
macro_rules! md (
|
macro_rules! md (
|
||||||
($name:expr, $op:expr, $equal:expr) => { {
|
($name:expr, $op:expr, $equal:expr) => { {
|
||||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||||
|
|
|
@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
|
pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
|
fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
|
||||||
cs_same_method(|cx, span, exprs| {
|
cs_same_method(|cx, span, exprs| {
|
||||||
// create `a.<method>(); b.<method>(); c.<method>(); ...`
|
// create `a.<method>(); b.<method>(); c.<method>(); ...`
|
||||||
|
|
|
@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
|
pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||||
let attrs = vec!(cx.attribute(span, inline));
|
let attrs = vec!(cx.attribute(span, inline));
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
|
|
|
@ -21,11 +21,13 @@ use parse::token::InternedString;
|
||||||
use parse::token;
|
use parse::token;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
|
pub fn expand_deriving_decodable<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
span: span,
|
span: span,
|
||||||
attributes: Vec::new(),
|
attributes: Vec::new(),
|
||||||
|
@ -155,12 +157,14 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
|
||||||
/// Create a decoder for a single enum variant/struct:
|
/// Create a decoder for a single enum variant/struct:
|
||||||
/// - `outer_pat_path` is the path to this enum variant/struct
|
/// - `outer_pat_path` is the path to this enum variant/struct
|
||||||
/// - `getarg` should retrieve the `uint`-th field with name `@str`.
|
/// - `getarg` should retrieve the `uint`-th field with name `@str`.
|
||||||
fn decode_static_fields(cx: &mut ExtCtxt,
|
fn decode_static_fields<F>(cx: &mut ExtCtxt,
|
||||||
trait_span: Span,
|
trait_span: Span,
|
||||||
outer_pat_path: ast::Path,
|
outer_pat_path: ast::Path,
|
||||||
fields: &StaticFields,
|
fields: &StaticFields,
|
||||||
getarg: |&mut ExtCtxt, Span, InternedString, uint| -> P<Expr>)
|
mut getarg: F)
|
||||||
-> P<Expr> {
|
-> P<Expr> where
|
||||||
|
F: FnMut(&mut ExtCtxt, Span, InternedString, uint) -> P<Expr>,
|
||||||
|
{
|
||||||
match *fields {
|
match *fields {
|
||||||
Unnamed(ref fields) => {
|
Unnamed(ref fields) => {
|
||||||
let path_expr = cx.expr_path(outer_pat_path);
|
let path_expr = cx.expr_path(outer_pat_path);
|
||||||
|
|
|
@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_default(cx: &mut ExtCtxt,
|
pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||||
let attrs = vec!(cx.attribute(span, inline));
|
let attrs = vec!(cx.attribute(span, inline));
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
|
|
|
@ -97,11 +97,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token;
|
use parse::token;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
|
pub fn expand_deriving_encodable<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
span: span,
|
span: span,
|
||||||
attributes: Vec::new(),
|
attributes: Vec::new(),
|
||||||
|
|
|
@ -333,11 +333,13 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
|
||||||
|
|
||||||
|
|
||||||
impl<'a> TraitDef<'a> {
|
impl<'a> TraitDef<'a> {
|
||||||
pub fn expand(&self,
|
pub fn expand<F>(&self,
|
||||||
cx: &mut ExtCtxt,
|
cx: &mut ExtCtxt,
|
||||||
mitem: &ast::MetaItem,
|
mitem: &ast::MetaItem,
|
||||||
item: &ast::Item,
|
item: &ast::Item,
|
||||||
push: |P<ast::Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<ast::Item>),
|
||||||
|
{
|
||||||
let newitem = match item.node {
|
let newitem = match item.node {
|
||||||
ast::ItemStruct(ref struct_def, ref generics) => {
|
ast::ItemStruct(ref struct_def, ref generics) => {
|
||||||
self.expand_struct_def(cx,
|
self.expand_struct_def(cx,
|
||||||
|
@ -1309,14 +1311,16 @@ impl<'a> TraitDef<'a> {
|
||||||
|
|
||||||
/// Fold the fields. `use_foldl` controls whether this is done
|
/// Fold the fields. `use_foldl` controls whether this is done
|
||||||
/// left-to-right (`true`) or right-to-left (`false`).
|
/// left-to-right (`true`) or right-to-left (`false`).
|
||||||
pub fn cs_fold(use_foldl: bool,
|
pub fn cs_fold<F>(use_foldl: bool,
|
||||||
f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]| -> P<Expr>,
|
mut f: F,
|
||||||
base: P<Expr>,
|
base: P<Expr>,
|
||||||
enum_nonmatch_f: EnumNonMatchCollapsedFunc,
|
enum_nonmatch_f: EnumNonMatchCollapsedFunc,
|
||||||
cx: &mut ExtCtxt,
|
cx: &mut ExtCtxt,
|
||||||
trait_span: Span,
|
trait_span: Span,
|
||||||
substructure: &Substructure)
|
substructure: &Substructure)
|
||||||
-> P<Expr> {
|
-> P<Expr> where
|
||||||
|
F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>,
|
||||||
|
{
|
||||||
match *substructure.fields {
|
match *substructure.fields {
|
||||||
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
||||||
if use_foldl {
|
if use_foldl {
|
||||||
|
@ -1355,12 +1359,14 @@ pub fn cs_fold(use_foldl: bool,
|
||||||
/// self_2.method(__arg_1_2, __arg_2_2)])
|
/// self_2.method(__arg_1_2, __arg_2_2)])
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>,
|
pub fn cs_same_method<F>(f: F,
|
||||||
enum_nonmatch_f: EnumNonMatchCollapsedFunc,
|
enum_nonmatch_f: EnumNonMatchCollapsedFunc,
|
||||||
cx: &mut ExtCtxt,
|
cx: &mut ExtCtxt,
|
||||||
trait_span: Span,
|
trait_span: Span,
|
||||||
substructure: &Substructure)
|
substructure: &Substructure)
|
||||||
-> P<Expr> {
|
-> P<Expr> where
|
||||||
|
F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>,
|
||||||
|
{
|
||||||
match *substructure.fields {
|
match *substructure.fields {
|
||||||
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
||||||
// call self_n.method(other_1_n, other_2_n, ...)
|
// call self_n.method(other_1_n, other_2_n, ...)
|
||||||
|
@ -1388,14 +1394,16 @@ pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>,
|
||||||
/// fields. `use_foldl` controls whether this is done left-to-right
|
/// fields. `use_foldl` controls whether this is done left-to-right
|
||||||
/// (`true`) or right-to-left (`false`).
|
/// (`true`) or right-to-left (`false`).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cs_same_method_fold(use_foldl: bool,
|
pub fn cs_same_method_fold<F>(use_foldl: bool,
|
||||||
f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>| -> P<Expr>,
|
mut f: F,
|
||||||
base: P<Expr>,
|
base: P<Expr>,
|
||||||
enum_nonmatch_f: EnumNonMatchCollapsedFunc,
|
enum_nonmatch_f: EnumNonMatchCollapsedFunc,
|
||||||
cx: &mut ExtCtxt,
|
cx: &mut ExtCtxt,
|
||||||
trait_span: Span,
|
trait_span: Span,
|
||||||
substructure: &Substructure)
|
substructure: &Substructure)
|
||||||
-> P<Expr> {
|
-> P<Expr> where
|
||||||
|
F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>) -> P<Expr>,
|
||||||
|
{
|
||||||
cs_same_method(
|
cs_same_method(
|
||||||
|cx, span, vals| {
|
|cx, span, vals| {
|
||||||
if use_foldl {
|
if use_foldl {
|
||||||
|
|
|
@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_hash(cx: &mut ExtCtxt,
|
pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
|
|
||||||
let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
|
let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
|
||||||
(Path::new_(vec!("std", "hash", "Hash"), None,
|
(Path::new_(vec!("std", "hash", "Hash"), None,
|
||||||
|
|
|
@ -18,11 +18,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
|
pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||||
let attrs = vec!(cx.attribute(span, inline));
|
let attrs = vec!(cx.attribute(span, inline));
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
|
|
|
@ -17,11 +17,13 @@ use ext::deriving::generic::*;
|
||||||
use ext::deriving::generic::ty::*;
|
use ext::deriving::generic::ty::*;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_rand(cx: &mut ExtCtxt,
|
pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
span: span,
|
span: span,
|
||||||
attributes: Vec::new(),
|
attributes: Vec::new(),
|
||||||
|
@ -64,7 +66,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
|
||||||
cx.ident_of("Rand"),
|
cx.ident_of("Rand"),
|
||||||
cx.ident_of("rand")
|
cx.ident_of("rand")
|
||||||
);
|
);
|
||||||
let rand_call = |cx: &mut ExtCtxt, span| {
|
let mut rand_call = |&mut: cx: &mut ExtCtxt, span| {
|
||||||
cx.expr_call_global(span,
|
cx.expr_call_global(span,
|
||||||
rand_ident.clone(),
|
rand_ident.clone(),
|
||||||
vec!(rng.clone()))
|
vec!(rng.clone()))
|
||||||
|
@ -133,12 +135,14 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
|
||||||
_ => cx.bug("Non-static method in `deriving(Rand)`")
|
_ => cx.bug("Non-static method in `deriving(Rand)`")
|
||||||
};
|
};
|
||||||
|
|
||||||
fn rand_thing(cx: &mut ExtCtxt,
|
fn rand_thing<F>(cx: &mut ExtCtxt,
|
||||||
trait_span: Span,
|
trait_span: Span,
|
||||||
ctor_path: ast::Path,
|
ctor_path: ast::Path,
|
||||||
summary: &StaticFields,
|
summary: &StaticFields,
|
||||||
rand_call: |&mut ExtCtxt, Span| -> P<Expr>)
|
mut rand_call: F)
|
||||||
-> P<Expr> {
|
-> P<Expr> where
|
||||||
|
F: FnMut(&mut ExtCtxt, Span) -> P<Expr>,
|
||||||
|
{
|
||||||
let path = cx.expr_path(ctor_path.clone());
|
let path = cx.expr_path(ctor_path.clone());
|
||||||
match *summary {
|
match *summary {
|
||||||
Unnamed(ref fields) => {
|
Unnamed(ref fields) => {
|
||||||
|
|
|
@ -21,11 +21,13 @@ use ptr::P;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub fn expand_deriving_show(cx: &mut ExtCtxt,
|
pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
// &mut ::std::fmt::Formatter
|
// &mut ::std::fmt::Formatter
|
||||||
let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
|
let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
|
||||||
Borrowed(None, ast::MutMutable));
|
Borrowed(None, ast::MutMutable));
|
||||||
|
|
|
@ -17,11 +17,13 @@ use ext::deriving::generic::ty::*;
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
pub fn expand_deriving_zero(cx: &mut ExtCtxt,
|
pub fn expand_deriving_zero<F>(cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
push: |P<Item>|) {
|
push: F) where
|
||||||
|
F: FnOnce(P<Item>),
|
||||||
|
{
|
||||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||||
let attrs = vec!(cx.attribute(span, inline));
|
let attrs = vec!(cx.attribute(span, inline));
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
|
|
|
@ -238,11 +238,13 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
|
||||||
/// of expansion and the mark which must be applied to the result.
|
/// of expansion and the mark which must be applied to the result.
|
||||||
/// Our current interface doesn't allow us to apply the mark to the
|
/// Our current interface doesn't allow us to apply the mark to the
|
||||||
/// result until after calling make_expr, make_items, etc.
|
/// result until after calling make_expr, make_items, etc.
|
||||||
fn expand_mac_invoc<T>(mac: ast::Mac, span: codemap::Span,
|
fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
|
||||||
parse_thunk: |Box<MacResult>|->Option<T>,
|
parse_thunk: F,
|
||||||
mark_thunk: |T,Mrk|->T,
|
mark_thunk: G,
|
||||||
fld: &mut MacroExpander)
|
fld: &mut MacroExpander)
|
||||||
-> Option<T>
|
-> Option<T> where
|
||||||
|
F: FnOnce(Box<MacResult>) -> Option<T>,
|
||||||
|
G: FnOnce(T, Mrk) -> T,
|
||||||
{
|
{
|
||||||
match mac.node {
|
match mac.node {
|
||||||
// it would almost certainly be cleaner to pass the whole
|
// it would almost certainly be cleaner to pass the whole
|
||||||
|
|
|
@ -105,9 +105,11 @@ pub fn apply_renames(renames: &RenameList, ctxt: SyntaxContext) -> SyntaxContext
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch the SCTable from TLS, create one if it doesn't yet exist.
|
/// Fetch the SCTable from TLS, create one if it doesn't yet exist.
|
||||||
pub fn with_sctable<T>(op: |&SCTable| -> T) -> T {
|
pub fn with_sctable<T, F>(op: F) -> T where
|
||||||
|
F: FnOnce(&SCTable) -> T,
|
||||||
|
{
|
||||||
thread_local!(static SCTABLE_KEY: SCTable = new_sctable_internal())
|
thread_local!(static SCTABLE_KEY: SCTable = new_sctable_internal())
|
||||||
SCTABLE_KEY.with(|slot| op(slot))
|
SCTABLE_KEY.with(move |slot| op(slot))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a fresh syntax context table with EmptyCtxt in slot zero
|
// Make a fresh syntax context table with EmptyCtxt in slot zero
|
||||||
|
@ -167,12 +169,14 @@ type ResolveTable = HashMap<(Name,SyntaxContext),Name>;
|
||||||
|
|
||||||
// okay, I admit, putting this in TLS is not so nice:
|
// okay, I admit, putting this in TLS is not so nice:
|
||||||
// fetch the SCTable from TLS, create one if it doesn't yet exist.
|
// fetch the SCTable from TLS, create one if it doesn't yet exist.
|
||||||
fn with_resolve_table_mut<T>(op: |&mut ResolveTable| -> T) -> T {
|
fn with_resolve_table_mut<T, F>(op: F) -> T where
|
||||||
|
F: FnOnce(&mut ResolveTable) -> T,
|
||||||
|
{
|
||||||
thread_local!(static RESOLVE_TABLE_KEY: RefCell<ResolveTable> = {
|
thread_local!(static RESOLVE_TABLE_KEY: RefCell<ResolveTable> = {
|
||||||
RefCell::new(HashMap::new())
|
RefCell::new(HashMap::new())
|
||||||
})
|
})
|
||||||
|
|
||||||
RESOLVE_TABLE_KEY.with(|slot| op(&mut *slot.borrow_mut()))
|
RESOLVE_TABLE_KEY.with(move |slot| op(&mut *slot.borrow_mut()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve a syntax object to a name, per MTWT.
|
/// Resolve a syntax object to a name, per MTWT.
|
||||||
|
|
|
@ -32,11 +32,11 @@ use std::rc::Rc;
|
||||||
|
|
||||||
// This could have a better place to live.
|
// This could have a better place to live.
|
||||||
pub trait MoveMap<T> {
|
pub trait MoveMap<T> {
|
||||||
fn move_map(self, f: |T| -> T) -> Self;
|
fn move_map<F>(self, f: F) -> Self where F: FnMut(T) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> MoveMap<T> for Vec<T> {
|
impl<T> MoveMap<T> for Vec<T> {
|
||||||
fn move_map(mut self, f: |T| -> T) -> Vec<T> {
|
fn move_map<F>(mut self, mut f: F) -> Vec<T> where F: FnMut(T) -> T {
|
||||||
for p in self.iter_mut() {
|
for p in self.iter_mut() {
|
||||||
unsafe {
|
unsafe {
|
||||||
// FIXME(#5016) this shouldn't need to zero to be safe.
|
// FIXME(#5016) this shouldn't need to zero to be safe.
|
||||||
|
@ -48,7 +48,7 @@ impl<T> MoveMap<T> for Vec<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> MoveMap<T> for OwnedSlice<T> {
|
impl<T> MoveMap<T> for OwnedSlice<T> {
|
||||||
fn move_map(self, f: |T| -> T) -> OwnedSlice<T> {
|
fn move_map<F>(self, f: F) -> OwnedSlice<T> where F: FnMut(T) -> T {
|
||||||
OwnedSlice::from_vec(self.into_vec().move_map(f))
|
OwnedSlice::from_vec(self.into_vec().move_map(f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,9 @@ impl<'a> StringReader<'a> {
|
||||||
/// Calls `f` with a string slice of the source text spanning from `start`
|
/// Calls `f` with a string slice of the source text spanning from `start`
|
||||||
/// up to but excluding `self.last_pos`, meaning the slice does not include
|
/// up to but excluding `self.last_pos`, meaning the slice does not include
|
||||||
/// the character `self.curr`.
|
/// the character `self.curr`.
|
||||||
pub fn with_str_from<T>(&self, start: BytePos, f: |s: &str| -> T) -> T {
|
pub fn with_str_from<T, F>(&self, start: BytePos, f: F) -> T where
|
||||||
|
F: FnOnce(&str) -> T,
|
||||||
|
{
|
||||||
self.with_str_from_to(start, self.last_pos, f)
|
self.with_str_from_to(start, self.last_pos, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +266,9 @@ impl<'a> StringReader<'a> {
|
||||||
|
|
||||||
/// Calls `f` with a string slice of the source text spanning from `start`
|
/// Calls `f` with a string slice of the source text spanning from `start`
|
||||||
/// up to but excluding `end`.
|
/// up to but excluding `end`.
|
||||||
fn with_str_from_to<T>(&self, start: BytePos, end: BytePos, f: |s: &str| -> T) -> T {
|
fn with_str_from_to<T, F>(&self, start: BytePos, end: BytePos, f: F) -> T where
|
||||||
|
F: FnOnce(&str) -> T,
|
||||||
|
{
|
||||||
f(self.filemap.src.slice(
|
f(self.filemap.src.slice(
|
||||||
self.byte_offset(start).to_uint(),
|
self.byte_offset(start).to_uint(),
|
||||||
self.byte_offset(end).to_uint()))
|
self.byte_offset(end).to_uint()))
|
||||||
|
|
|
@ -718,11 +718,12 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
|
/// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
|
||||||
fn parse_seq_to_before_or<T>(
|
fn parse_seq_to_before_or<T, F>(&mut self,
|
||||||
&mut self,
|
sep: &token::Token,
|
||||||
sep: &token::Token,
|
mut f: F)
|
||||||
f: |&mut Parser| -> T)
|
-> Vec<T> where
|
||||||
-> Vec<T> {
|
F: FnMut(&mut Parser) -> T,
|
||||||
|
{
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
let mut vector = Vec::new();
|
let mut vector = Vec::new();
|
||||||
while self.token != token::BinOp(token::Or) &&
|
while self.token != token::BinOp(token::Or) &&
|
||||||
|
@ -769,10 +770,12 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_seq_to_before_gt_or_return<T>(&mut self,
|
pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
|
||||||
sep: Option<token::Token>,
|
sep: Option<token::Token>,
|
||||||
f: |&mut Parser| -> Option<T>)
|
mut f: F)
|
||||||
-> (OwnedSlice<T>, bool) {
|
-> (OwnedSlice<T>, bool) where
|
||||||
|
F: FnMut(&mut Parser) -> Option<T>,
|
||||||
|
{
|
||||||
let mut v = Vec::new();
|
let mut v = Vec::new();
|
||||||
// This loop works by alternating back and forth between parsing types
|
// This loop works by alternating back and forth between parsing types
|
||||||
// and commas. For example, given a string `A, B,>`, the parser would
|
// and commas. For example, given a string `A, B,>`, the parser would
|
||||||
|
@ -802,28 +805,34 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Parse a sequence bracketed by '<' and '>', stopping
|
/// Parse a sequence bracketed by '<' and '>', stopping
|
||||||
/// before the '>'.
|
/// before the '>'.
|
||||||
pub fn parse_seq_to_before_gt<T>(&mut self,
|
pub fn parse_seq_to_before_gt<T, F>(&mut self,
|
||||||
sep: Option<token::Token>,
|
sep: Option<token::Token>,
|
||||||
f: |&mut Parser| -> T)
|
mut f: F)
|
||||||
-> OwnedSlice<T> {
|
-> OwnedSlice<T> where
|
||||||
|
F: FnMut(&mut Parser) -> T,
|
||||||
|
{
|
||||||
let (result, returned) = self.parse_seq_to_before_gt_or_return(sep, |p| Some(f(p)));
|
let (result, returned) = self.parse_seq_to_before_gt_or_return(sep, |p| Some(f(p)));
|
||||||
assert!(!returned);
|
assert!(!returned);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_seq_to_gt<T>(&mut self,
|
pub fn parse_seq_to_gt<T, F>(&mut self,
|
||||||
sep: Option<token::Token>,
|
sep: Option<token::Token>,
|
||||||
f: |&mut Parser| -> T)
|
f: F)
|
||||||
-> OwnedSlice<T> {
|
-> OwnedSlice<T> where
|
||||||
|
F: FnMut(&mut Parser) -> T,
|
||||||
|
{
|
||||||
let v = self.parse_seq_to_before_gt(sep, f);
|
let v = self.parse_seq_to_before_gt(sep, f);
|
||||||
self.expect_gt();
|
self.expect_gt();
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_seq_to_gt_or_return<T>(&mut self,
|
pub fn parse_seq_to_gt_or_return<T, F>(&mut self,
|
||||||
sep: Option<token::Token>,
|
sep: Option<token::Token>,
|
||||||
f: |&mut Parser| -> Option<T>)
|
f: F)
|
||||||
-> (OwnedSlice<T>, bool) {
|
-> (OwnedSlice<T>, bool) where
|
||||||
|
F: FnMut(&mut Parser) -> Option<T>,
|
||||||
|
{
|
||||||
let (v, returned) = self.parse_seq_to_before_gt_or_return(sep, f);
|
let (v, returned) = self.parse_seq_to_before_gt_or_return(sep, f);
|
||||||
if !returned {
|
if !returned {
|
||||||
self.expect_gt();
|
self.expect_gt();
|
||||||
|
@ -834,12 +843,13 @@ impl<'a> Parser<'a> {
|
||||||
/// Parse a sequence, including the closing delimiter. The function
|
/// Parse a sequence, including the closing delimiter. The function
|
||||||
/// f must consume tokens until reaching the next separator or
|
/// f must consume tokens until reaching the next separator or
|
||||||
/// closing bracket.
|
/// closing bracket.
|
||||||
pub fn parse_seq_to_end<T>(
|
pub fn parse_seq_to_end<T, F>(&mut self,
|
||||||
&mut self,
|
ket: &token::Token,
|
||||||
ket: &token::Token,
|
sep: SeqSep,
|
||||||
sep: SeqSep,
|
f: F)
|
||||||
f: |&mut Parser| -> T)
|
-> Vec<T> where
|
||||||
-> Vec<T> {
|
F: FnMut(&mut Parser) -> T,
|
||||||
|
{
|
||||||
let val = self.parse_seq_to_before_end(ket, sep, f);
|
let val = self.parse_seq_to_before_end(ket, sep, f);
|
||||||
self.bump();
|
self.bump();
|
||||||
val
|
val
|
||||||
|
@ -848,12 +858,13 @@ impl<'a> Parser<'a> {
|
||||||
/// Parse a sequence, not including the closing delimiter. The function
|
/// Parse a sequence, not including the closing delimiter. The function
|
||||||
/// f must consume tokens until reaching the next separator or
|
/// f must consume tokens until reaching the next separator or
|
||||||
/// closing bracket.
|
/// closing bracket.
|
||||||
pub fn parse_seq_to_before_end<T>(
|
pub fn parse_seq_to_before_end<T, F>(&mut self,
|
||||||
&mut self,
|
ket: &token::Token,
|
||||||
ket: &token::Token,
|
sep: SeqSep,
|
||||||
sep: SeqSep,
|
mut f: F)
|
||||||
f: |&mut Parser| -> T)
|
-> Vec<T> where
|
||||||
-> Vec<T> {
|
F: FnMut(&mut Parser) -> T,
|
||||||
|
{
|
||||||
let mut first: bool = true;
|
let mut first: bool = true;
|
||||||
let mut v = vec!();
|
let mut v = vec!();
|
||||||
while self.token != *ket {
|
while self.token != *ket {
|
||||||
|
@ -873,13 +884,14 @@ impl<'a> Parser<'a> {
|
||||||
/// Parse a sequence, including the closing delimiter. The function
|
/// Parse a sequence, including the closing delimiter. The function
|
||||||
/// f must consume tokens until reaching the next separator or
|
/// f must consume tokens until reaching the next separator or
|
||||||
/// closing bracket.
|
/// closing bracket.
|
||||||
pub fn parse_unspanned_seq<T>(
|
pub fn parse_unspanned_seq<T, F>(&mut self,
|
||||||
&mut self,
|
bra: &token::Token,
|
||||||
bra: &token::Token,
|
ket: &token::Token,
|
||||||
ket: &token::Token,
|
sep: SeqSep,
|
||||||
sep: SeqSep,
|
f: F)
|
||||||
f: |&mut Parser| -> T)
|
-> Vec<T> where
|
||||||
-> Vec<T> {
|
F: FnMut(&mut Parser) -> T,
|
||||||
|
{
|
||||||
self.expect(bra);
|
self.expect(bra);
|
||||||
let result = self.parse_seq_to_before_end(ket, sep, f);
|
let result = self.parse_seq_to_before_end(ket, sep, f);
|
||||||
self.bump();
|
self.bump();
|
||||||
|
@ -888,13 +900,14 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Parse a sequence parameter of enum variant. For consistency purposes,
|
/// Parse a sequence parameter of enum variant. For consistency purposes,
|
||||||
/// these should not be empty.
|
/// these should not be empty.
|
||||||
pub fn parse_enum_variant_seq<T>(
|
pub fn parse_enum_variant_seq<T, F>(&mut self,
|
||||||
&mut self,
|
bra: &token::Token,
|
||||||
bra: &token::Token,
|
ket: &token::Token,
|
||||||
ket: &token::Token,
|
sep: SeqSep,
|
||||||
sep: SeqSep,
|
f: F)
|
||||||
f: |&mut Parser| -> T)
|
-> Vec<T> where
|
||||||
-> Vec<T> {
|
F: FnMut(&mut Parser) -> T,
|
||||||
|
{
|
||||||
let result = self.parse_unspanned_seq(bra, ket, sep, f);
|
let result = self.parse_unspanned_seq(bra, ket, sep, f);
|
||||||
if result.is_empty() {
|
if result.is_empty() {
|
||||||
let last_span = self.last_span;
|
let last_span = self.last_span;
|
||||||
|
@ -906,13 +919,14 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
// NB: Do not use this function unless you actually plan to place the
|
// NB: Do not use this function unless you actually plan to place the
|
||||||
// spanned list in the AST.
|
// spanned list in the AST.
|
||||||
pub fn parse_seq<T>(
|
pub fn parse_seq<T, F>(&mut self,
|
||||||
&mut self,
|
bra: &token::Token,
|
||||||
bra: &token::Token,
|
ket: &token::Token,
|
||||||
ket: &token::Token,
|
sep: SeqSep,
|
||||||
sep: SeqSep,
|
f: F)
|
||||||
f: |&mut Parser| -> T)
|
-> Spanned<Vec<T>> where
|
||||||
-> Spanned<Vec<T> > {
|
F: FnMut(&mut Parser) -> T,
|
||||||
|
{
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
self.expect(bra);
|
self.expect(bra);
|
||||||
let result = self.parse_seq_to_before_end(ket, sep, f);
|
let result = self.parse_seq_to_before_end(ket, sep, f);
|
||||||
|
@ -972,8 +986,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
return (4 - self.buffer_start) + self.buffer_end;
|
return (4 - self.buffer_start) + self.buffer_end;
|
||||||
}
|
}
|
||||||
pub fn look_ahead<R>(&mut self, distance: uint, f: |&token::Token| -> R)
|
pub fn look_ahead<R, F>(&mut self, distance: uint, f: F) -> R where
|
||||||
-> R {
|
F: FnOnce(&token::Token) -> R,
|
||||||
|
{
|
||||||
let dist = distance as int;
|
let dist = distance as int;
|
||||||
while self.buffer_length() < dist {
|
while self.buffer_length() < dist {
|
||||||
self.buffer[self.buffer_end as uint] = self.reader.real_token();
|
self.buffer[self.buffer_end as uint] = self.reader.real_token();
|
||||||
|
@ -4285,8 +4300,9 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Parse the argument list and result type of a function
|
/// Parse the argument list and result type of a function
|
||||||
/// that may have a self type.
|
/// that may have a self type.
|
||||||
fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> Arg)
|
fn parse_fn_decl_with_self<F>(&mut self, parse_arg_fn: F) -> (ExplicitSelf, P<FnDecl>) where
|
||||||
-> (ExplicitSelf, P<FnDecl>) {
|
F: FnMut(&mut Parser) -> Arg,
|
||||||
|
{
|
||||||
fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
|
fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
|
||||||
-> ast::ExplicitSelf_ {
|
-> ast::ExplicitSelf_ {
|
||||||
// The following things are possible to see here:
|
// The following things are possible to see here:
|
||||||
|
|
|
@ -165,7 +165,9 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_string(f: |&mut State| -> IoResult<()>) -> String {
|
pub fn to_string<F>(f: F) -> String where
|
||||||
|
F: FnOnce(&mut State) -> IoResult<()>,
|
||||||
|
{
|
||||||
use std::raw::TraitObject;
|
use std::raw::TraitObject;
|
||||||
let mut s = rust_printer(box Vec::new());
|
let mut s = rust_printer(box Vec::new());
|
||||||
f(&mut s).unwrap();
|
f(&mut s).unwrap();
|
||||||
|
@ -426,8 +428,10 @@ pub mod with_hygiene {
|
||||||
|
|
||||||
// This function is the trick that all the rest of the routines
|
// This function is the trick that all the rest of the routines
|
||||||
// hang on.
|
// hang on.
|
||||||
pub fn to_string_hyg(f: |&mut super::State| -> IoResult<()>) -> String {
|
pub fn to_string_hyg<F>(f: F) -> String where
|
||||||
super::to_string(|s| {
|
F: FnOnce(&mut super::State) -> IoResult<()>,
|
||||||
|
{
|
||||||
|
super::to_string(move |s| {
|
||||||
s.encode_idents_with_hygiene = true;
|
s.encode_idents_with_hygiene = true;
|
||||||
f(s)
|
f(s)
|
||||||
})
|
})
|
||||||
|
@ -580,9 +584,9 @@ impl<'a> State<'a> {
|
||||||
word(&mut self.s, "*/")
|
word(&mut self.s, "*/")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commasep<T>(&mut self, b: Breaks, elts: &[T],
|
pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> IoResult<()> where
|
||||||
op: |&mut State, &T| -> IoResult<()>)
|
F: FnMut(&mut State, &T) -> IoResult<()>,
|
||||||
-> IoResult<()> {
|
{
|
||||||
try!(self.rbox(0u, b));
|
try!(self.rbox(0u, b));
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for elt in elts.iter() {
|
for elt in elts.iter() {
|
||||||
|
@ -593,12 +597,14 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn commasep_cmnt<T>(
|
pub fn commasep_cmnt<T, F, G>(&mut self,
|
||||||
&mut self,
|
b: Breaks,
|
||||||
b: Breaks,
|
elts: &[T],
|
||||||
elts: &[T],
|
mut op: F,
|
||||||
op: |&mut State, &T| -> IoResult<()>,
|
mut get_span: G) -> IoResult<()> where
|
||||||
get_span: |&T| -> codemap::Span) -> IoResult<()> {
|
F: FnMut(&mut State, &T) -> IoResult<()>,
|
||||||
|
G: FnMut(&T) -> codemap::Span,
|
||||||
|
{
|
||||||
try!(self.rbox(0u, b));
|
try!(self.rbox(0u, b));
|
||||||
let len = elts.len();
|
let len = elts.len();
|
||||||
let mut i = 0u;
|
let mut i = 0u;
|
||||||
|
|
|
@ -56,12 +56,16 @@ pub fn P<T: 'static>(value: T) -> P<T> {
|
||||||
impl<T: 'static> P<T> {
|
impl<T: 'static> P<T> {
|
||||||
/// Move out of the pointer.
|
/// Move out of the pointer.
|
||||||
/// Intended for chaining transformations not covered by `map`.
|
/// Intended for chaining transformations not covered by `map`.
|
||||||
pub fn and_then<U>(self, f: |T| -> U) -> U {
|
pub fn and_then<U, F>(self, f: F) -> U where
|
||||||
|
F: FnOnce(T) -> U,
|
||||||
|
{
|
||||||
f(*self.ptr)
|
f(*self.ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transform the inner value, consuming `self` and producing a new `P<T>`.
|
/// Transform the inner value, consuming `self` and producing a new `P<T>`.
|
||||||
pub fn map(mut self, f: |T| -> T) -> P<T> {
|
pub fn map<F>(mut self, f: F) -> P<T> where
|
||||||
|
F: FnOnce(T) -> T,
|
||||||
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let p = &mut *self.ptr;
|
let p = &mut *self.ptr;
|
||||||
// FIXME(#5016) this shouldn't need to zero to be safe.
|
// FIXME(#5016) this shouldn't need to zero to be safe.
|
||||||
|
|
|
@ -31,7 +31,9 @@ pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a>
|
||||||
source_str)
|
source_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_error_checking_parse<T>(s: String, f: |&mut Parser| -> T) -> T {
|
fn with_error_checking_parse<T, F>(s: String, f: F) -> T where
|
||||||
|
F: FnOnce(&mut Parser) -> T,
|
||||||
|
{
|
||||||
let ps = new_parse_sess();
|
let ps = new_parse_sess();
|
||||||
let mut p = string_to_parser(&ps, s);
|
let mut p = string_to_parser(&ps, s);
|
||||||
let x = f(&mut p);
|
let x = f(&mut p);
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl<T> Iterator<T> for MoveItems<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> MoveMap<T> for SmallVector<T> {
|
impl<T> MoveMap<T> for SmallVector<T> {
|
||||||
fn move_map(self, f: |T| -> T) -> SmallVector<T> {
|
fn move_map<F>(self, mut f: F) -> SmallVector<T> where F: FnMut(T) -> T {
|
||||||
let repr = match self.repr {
|
let repr = match self.repr {
|
||||||
Zero => Zero,
|
Zero => Zero,
|
||||||
One(v) => One(f(v)),
|
One(v) => One(f(v)),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue