To allow these braced macro invocation, this PR removes the optional expression from `ast::Block` and instead uses a `StmtKind::Expr` at the end of the statement list.
Currently, braced macro invocations in blocks can expand into statements (and items) except when they are last in a block, in which case they can only expand into expressions.
For example,
```rust
macro_rules! make_stmt {
() => { let x = 0; }
}
fn f() {
make_stmt! {} //< This is OK...
let x = 0; //< ... unless this line is commented out.
}
```
Fixes #34418.
use std::collections::BTreeMap;
use std::iter;
use syntax::ast::*;
-use syntax::attr::{ThinAttributes, ThinAttributesExt};
use syntax::ptr::P;
-use syntax::codemap::{respan, Spanned, Span};
+use syntax::codemap::{respan, Spanned};
use syntax::parse::token;
use syntax::std_inject;
use syntax::visit::{self, Visitor};
+use syntax_pos::Span;
pub struct LoweringContext<'a> {
crate_root: Option<&'static str>,
lctx: &'lcx mut LoweringContext<'interner>,
}
- impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
- fn visit_item(&mut self, item: &'lcx Item) {
+ impl<'lcx, 'interner> Visitor for ItemLowerer<'lcx, 'interner> {
+ fn visit_item(&mut self, item: &Item) {
self.items.insert(item.id, self.lctx.lower_item(item));
visit::walk_item(self, item);
}
}
}
- fn lower_decl(&mut self, d: &Decl) -> P<hir::Decl> {
- match d.node {
- DeclKind::Local(ref l) => P(Spanned {
- node: hir::DeclLocal(self.lower_local(l)),
- span: d.span,
- }),
- DeclKind::Item(ref it) => P(Spanned {
- node: hir::DeclItem(self.lower_item_id(it)),
- span: d.span,
- }),
- }
- }
-
fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
hir::TypeBinding {
id: b.id,
}
fn lower_block(&mut self, b: &Block) -> P<hir::Block> {
+ let mut stmts = Vec::new();
+ let mut expr = None;
+
+ if let Some((last, rest)) = b.stmts.split_last() {
+ stmts = rest.iter().map(|s| self.lower_stmt(s)).collect::<Vec<_>>();
+ let last = self.lower_stmt(last);
+ if let hir::StmtExpr(e, _) = last.node {
+ expr = Some(e);
+ } else {
+ stmts.push(last);
+ }
+ }
+
P(hir::Block {
id: b.id,
- stmts: b.stmts.iter().map(|s| self.lower_stmt(s)).collect(),
- expr: b.expr.as_ref().map(|ref x| self.lower_expr(x)),
+ stmts: stmts.into(),
+ expr: expr,
rules: self.lower_block_check_mode(&b.rules),
span: b.span,
})
hir::TypeTraitItem(this.lower_bounds(bounds),
default.as_ref().map(|x| this.lower_ty(x)))
}
+ TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
},
span: i.span,
}
pats.iter().map(|x| self.lower_pat(x)).collect(),
ddpos)
}
- PatKind::Path(ref pth) => {
+ PatKind::Path(None, ref pth) => {
hir::PatKind::Path(self.lower_path(pth))
}
- PatKind::QPath(ref qself, ref pth) => {
+ PatKind::Path(Some(ref qself), ref pth) => {
let qself = hir::QSelf {
ty: self.lower_ty(&qself.ty),
position: qself.position,
let make_call = |this: &mut LoweringContext, p, args| {
let path = this.core_path(e.span, p);
- let path = this.expr_path(path, None);
- this.expr_call(e.span, path, args, None)
+ let path = this.expr_path(path, ThinVec::new());
+ this.expr_call(e.span, path, args)
};
let mk_stmt_let = |this: &mut LoweringContext, bind, expr| {
- this.stmt_let(e.span, false, bind, expr, None)
+ this.stmt_let(e.span, false, bind, expr)
};
let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| {
- this.stmt_let(e.span, true, bind, expr, None)
+ this.stmt_let(e.span, true, bind, expr)
};
// let placer = <placer_expr> ;
placer_expr,
e.span,
hir::PopUnstableBlock,
- None);
+ ThinVec::new());
mk_stmt_let(self, placer_ident, placer_expr)
};
// let mut place = Placer::make_place(placer);
let (s2, place_binding) = {
- let placer = self.expr_ident(e.span, placer_ident, None, placer_binding);
+ let placer = self.expr_ident(e.span, placer_ident, placer_binding);
let call = make_call(self, &make_place, hir_vec![placer]);
mk_stmt_let_mut(self, place_ident, call)
};
// let p_ptr = Place::pointer(&mut place);
let (s3, p_ptr_binding) = {
- let agent = self.expr_ident(e.span, place_ident, None, place_binding);
- let args = hir_vec![self.expr_mut_addr_of(e.span, agent, None)];
+ let agent = self.expr_ident(e.span, place_ident, place_binding);
+ let args = hir_vec![self.expr_mut_addr_of(e.span, agent)];
let call = make_call(self, &place_pointer, args);
mk_stmt_let(self, p_ptr_ident, call)
};
value_expr,
e.span,
hir::PopUnstableBlock,
- None);
+ ThinVec::new());
self.signal_block_expr(hir_vec![],
value_expr,
e.span,
- hir::PopUnsafeBlock(hir::CompilerGenerated), None)
+ hir::PopUnsafeBlock(hir::CompilerGenerated),
+ ThinVec::new())
};
// push_unsafe!({
// InPlace::finalize(place)
// })
let expr = {
- let ptr = self.expr_ident(e.span, p_ptr_ident, None, p_ptr_binding);
+ let ptr = self.expr_ident(e.span, p_ptr_ident, p_ptr_binding);
let call_move_val_init =
hir::StmtSemi(
make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
self.next_id());
let call_move_val_init = respan(e.span, call_move_val_init);
- let place = self.expr_ident(e.span, place_ident, None, place_binding);
+ let place = self.expr_ident(e.span, place_ident, place_binding);
let call = make_call(self, &inplace_finalize, hir_vec![place]);
self.signal_block_expr(hir_vec![call_move_val_init],
call,
e.span,
- hir::PushUnsafeBlock(hir::CompilerGenerated), None)
+ hir::PushUnsafeBlock(hir::CompilerGenerated),
+ ThinVec::new())
};
return self.signal_block_expr(hir_vec![s1, s2, s3],
rules: hir::DefaultBlock,
span: span,
});
- self.expr_block(blk, None)
+ self.expr_block(blk, ThinVec::new())
}
_ => self.lower_expr(els),
}
expr,
e.span,
hir::PopUnstableBlock,
- None);
+ ThinVec::new());
this.field(token::intern(s), signal_block, ast_expr.span)
}).collect();
let attrs = ast_expr.attrs.clone();
hir_expr,
ast_expr.span,
hir::PushUnstableBlock,
- None)
+ ThinVec::new())
}
use syntax::ast::RangeLimits::*;
hir::ExprPath(hir_qself, self.lower_path(path))
}
ExprKind::Break(opt_ident) => hir::ExprBreak(self.lower_opt_sp_ident(opt_ident)),
- ExprKind::Again(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)),
+ ExprKind::Continue(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)),
ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| self.lower_expr(x))),
ExprKind::InlineAsm(InlineAsm {
ref inputs,
ex.span = e.span;
}
// merge attributes into the inner expression.
- ex.attrs.update(|attrs| {
- attrs.prepend(e.attrs.clone())
- });
+ let mut attrs = e.attrs.clone();
+ attrs.extend::<Vec<_>>(ex.attrs.into());
+ ex.attrs = attrs;
ex
});
}
// `<pat> => <body>`
let pat_arm = {
let body = self.lower_block(body);
- let body_expr = self.expr_block(body, None);
+ let body_expr = self.expr_block(body, ThinVec::new());
let pat = self.lower_pat(pat);
self.arm(hir_vec![pat], body_expr)
};
attrs: hir_vec![],
pats: hir_vec![pat_under],
guard: Some(cond),
- body: self.expr_block(then, None),
+ body: self.expr_block(then, ThinVec::new()),
});
else_opt.map(|else_opt| (else_opt, true))
}
let else_arm = {
let pat_under = self.pat_wild(e.span);
let else_expr =
- else_opt.unwrap_or_else(|| self.expr_tuple(e.span, hir_vec![], None));
+ else_opt.unwrap_or_else(|| self.expr_tuple(e.span, hir_vec![]));
self.arm(hir_vec![pat_under], else_expr)
};
// `<pat> => <body>`
let pat_arm = {
let body = self.lower_block(body);
- let body_expr = self.expr_block(body, None);
+ let body_expr = self.expr_block(body, ThinVec::new());
let pat = self.lower_pat(pat);
self.arm(hir_vec![pat], body_expr)
};
// `_ => break`
let break_arm = {
let pat_under = self.pat_wild(e.span);
- let break_expr = self.expr_break(e.span, None);
+ let break_expr = self.expr_break(e.span, ThinVec::new());
self.arm(hir_vec![pat_under], break_expr)
};
hir::ExprMatch(sub_expr,
arms,
hir::MatchSource::WhileLetDesugar),
- None);
+ ThinVec::new());
// `[opt_ident]: loop { ... }`
let loop_block = self.block_expr(match_expr);
id: self.next_id(),
node: hir::ExprBlock(body_block),
span: body_span,
- attrs: None,
+ attrs: ThinVec::new(),
});
let pat = self.lower_pat(pat);
let some_pat = self.pat_some(e.span, pat);
// `::std::option::Option::None => break`
let break_arm = {
- let break_expr = self.expr_break(e.span, None);
+ let break_expr = self.expr_break(e.span, ThinVec::new());
let pat = self.pat_none(e.span);
self.arm(hir_vec![pat], break_expr)
};
self.path_global(e.span, strs)
};
- let iter = self.expr_ident(e.span, iter, None, iter_pat.id);
- let ref_mut_iter = self.expr_mut_addr_of(e.span, iter, None);
- let next_path = self.expr_path(next_path, None);
- let next_expr = self.expr_call(e.span,
- next_path,
- hir_vec![ref_mut_iter],
- None);
+ let iter = self.expr_ident(e.span, iter, iter_pat.id);
+ let ref_mut_iter = self.expr_mut_addr_of(e.span, iter);
+ let next_path = self.expr_path(next_path, ThinVec::new());
+ let next_expr = self.expr_call(e.span, next_path, hir_vec![ref_mut_iter]);
let arms = hir_vec![pat_arm, break_arm];
self.expr(e.span,
hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar),
- None)
+ ThinVec::new())
};
// `[opt_ident]: loop { ... }`
let loop_block = self.block_expr(match_expr);
let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
- let loop_expr =
- P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None });
+ let loop_expr = P(hir::Expr {
+ id: e.id,
+ node: loop_expr,
+ span: e.span,
+ attrs: ThinVec::new(),
+ });
// `mut iter => { ... }`
let iter_arm = self.arm(hir_vec![iter_pat], loop_expr);
self.path_global(e.span, strs)
};
- let into_iter = self.expr_path(into_iter_path, None);
- self.expr_call(e.span, into_iter, hir_vec![head], None)
+ let into_iter = self.expr_path(into_iter_path, ThinVec::new());
+ self.expr_call(e.span, into_iter, hir_vec![head])
};
let match_expr = self.expr_match(e.span,
into_iter_expr,
hir_vec![iter_arm],
- hir::MatchSource::ForLoopDesugar,
- None);
+ hir::MatchSource::ForLoopDesugar);
// `{ let _result = ...; _result }`
// underscore prevents an unused_variables lint if the head diverges
let result_ident = self.str_to_ident("_result");
let (let_stmt, let_stmt_binding) =
- self.stmt_let(e.span, false, result_ident, match_expr, None);
+ self.stmt_let(e.span, false, result_ident, match_expr);
- let result = self.expr_ident(e.span, result_ident, None, let_stmt_binding);
+ let result = self.expr_ident(e.span, result_ident, let_stmt_binding);
let block = self.block_all(e.span, hir_vec![let_stmt], Some(result));
// add the attributes to the outer returned expr node
return self.expr_block(block, e.attrs.clone());
let ok_arm = {
let val_ident = self.str_to_ident("val");
let val_pat = self.pat_ident(e.span, val_ident);
- let val_expr = self.expr_ident(e.span, val_ident, None, val_pat.id);
+ let val_expr = self.expr_ident(e.span, val_ident, val_pat.id);
let ok_pat = self.pat_ok(e.span, val_pat);
self.arm(hir_vec![ok_pat], val_expr)
let from_expr = {
let path = self.std_path(&["convert", "From", "from"]);
let path = self.path_global(e.span, path);
- let from = self.expr_path(path, None);
- let err_expr = self.expr_ident(e.span, err_ident, None, err_local.id);
+ let from = self.expr_path(path, ThinVec::new());
+ let err_expr = self.expr_ident(e.span, err_ident, err_local.id);
- self.expr_call(e.span, from, hir_vec![err_expr], None)
+ self.expr_call(e.span, from, hir_vec![err_expr])
};
let err_expr = {
let path = self.std_path(&["result", "Result", "Err"]);
let path = self.path_global(e.span, path);
- let err_ctor = self.expr_path(path, None);
- self.expr_call(e.span, err_ctor, hir_vec![from_expr], None)
+ let err_ctor = self.expr_path(path, ThinVec::new());
+ self.expr_call(e.span, err_ctor, hir_vec![from_expr])
};
let err_pat = self.pat_err(e.span, err_local);
let ret_expr = self.expr(e.span,
- hir::Expr_::ExprRet(Some(err_expr)), None);
-
+ hir::Expr_::ExprRet(Some(err_expr)),
+ ThinVec::new());
self.arm(hir_vec![err_pat], ret_expr)
};
return self.expr_match(e.span, sub_expr, hir_vec![err_arm, ok_arm],
- hir::MatchSource::TryDesugar, None);
+ hir::MatchSource::TryDesugar);
}
ExprKind::Mac(_) => panic!("Shouldn't exist here"),
fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
match s.node {
- StmtKind::Decl(ref d, id) => {
- Spanned {
- node: hir::StmtDecl(self.lower_decl(d), id),
+ StmtKind::Local(ref l) => Spanned {
+ node: hir::StmtDecl(P(Spanned {
+ node: hir::DeclLocal(self.lower_local(l)),
span: s.span,
- }
- }
- StmtKind::Expr(ref e, id) => {
+ }), s.id),
+ span: s.span,
+ },
+ StmtKind::Item(ref it) => Spanned {
+ node: hir::StmtDecl(P(Spanned {
+ node: hir::DeclItem(self.lower_item_id(it)),
+ span: s.span,
+ }), s.id),
+ span: s.span,
+ },
+ StmtKind::Expr(ref e) => {
Spanned {
- node: hir::StmtExpr(self.lower_expr(e), id),
+ node: hir::StmtExpr(self.lower_expr(e), s.id),
span: s.span,
}
}
- StmtKind::Semi(ref e, id) => {
+ StmtKind::Semi(ref e) => {
Spanned {
- node: hir::StmtSemi(self.lower_expr(e), id),
+ node: hir::StmtSemi(self.lower_expr(e), s.id),
span: s.span,
}
}
}
}
- fn expr_break(&mut self, span: Span, attrs: ThinAttributes) -> P<hir::Expr> {
+ fn expr_break(&mut self, span: Span, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
self.expr(span, hir::ExprBreak(None), attrs)
}
- fn expr_call(&mut self,
- span: Span,
- e: P<hir::Expr>,
- args: hir::HirVec<P<hir::Expr>>,
- attrs: ThinAttributes)
+ fn expr_call(&mut self, span: Span, e: P<hir::Expr>, args: hir::HirVec<P<hir::Expr>>)
-> P<hir::Expr> {
- self.expr(span, hir::ExprCall(e, args), attrs)
+ self.expr(span, hir::ExprCall(e, args), ThinVec::new())
}
- fn expr_ident(&mut self, span: Span, id: Name, attrs: ThinAttributes, binding: NodeId)
- -> P<hir::Expr> {
+ fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> P<hir::Expr> {
let expr_path = hir::ExprPath(None, self.path_ident(span, id));
- let expr = self.expr(span, expr_path, attrs);
+ let expr = self.expr(span, expr_path, ThinVec::new());
let def = self.resolver.definitions().map(|defs| {
Def::Local(defs.local_def_id(binding), binding)
expr
}
- fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>, attrs: ThinAttributes)
- -> P<hir::Expr> {
- self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), attrs)
+ fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> P<hir::Expr> {
+ self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new())
}
- fn expr_path(&mut self, path: hir::Path, attrs: ThinAttributes) -> P<hir::Expr> {
+ fn expr_path(&mut self, path: hir::Path, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
let def = self.resolver.resolve_generated_global_path(&path, true);
let expr = self.expr(path.span, hir::ExprPath(None, path), attrs);
self.resolver.record_resolution(expr.id, def);
span: Span,
arg: P<hir::Expr>,
arms: hir::HirVec<hir::Arm>,
- source: hir::MatchSource,
- attrs: ThinAttributes)
+ source: hir::MatchSource)
-> P<hir::Expr> {
- self.expr(span, hir::ExprMatch(arg, arms, source), attrs)
+ self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new())
}
- fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinAttributes) -> P<hir::Expr> {
+ fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
self.expr(b.span, hir::ExprBlock(b), attrs)
}
- fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<P<hir::Expr>>, attrs: ThinAttributes)
- -> P<hir::Expr> {
- self.expr(sp, hir::ExprTup(exprs), attrs)
+ fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<P<hir::Expr>>) -> P<hir::Expr> {
+ self.expr(sp, hir::ExprTup(exprs), ThinVec::new())
}
fn expr_struct(&mut self,
path: hir::Path,
fields: hir::HirVec<hir::Field>,
e: Option<P<hir::Expr>>,
- attrs: ThinAttributes) -> P<hir::Expr> {
+ attrs: ThinVec<Attribute>) -> P<hir::Expr> {
let def = self.resolver.resolve_generated_global_path(&path, false);
let expr = self.expr(sp, hir::ExprStruct(path, fields, e), attrs);
self.resolver.record_resolution(expr.id, def);
expr
}
- fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinAttributes) -> P<hir::Expr> {
+ fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
P(hir::Expr {
id: self.next_id(),
node: node,
})
}
- fn stmt_let(&mut self,
- sp: Span,
- mutbl: bool,
- ident: Name,
- ex: P<hir::Expr>,
- attrs: ThinAttributes)
+ fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
-> (hir::Stmt, NodeId) {
let pat = if mutbl {
self.pat_ident_binding_mode(sp, ident, hir::BindByValue(hir::MutMutable))
init: Some(ex),
id: self.next_id(),
span: sp,
- attrs: attrs,
+ attrs: ThinVec::new(),
});
let decl = respan(sp, hir::DeclLocal(local));
(respan(sp, hir::StmtDecl(P(decl), self.next_id())), pat_id)
expr: P<hir::Expr>,
span: Span,
rule: hir::BlockCheckMode,
- attrs: ThinAttributes)
+ attrs: ThinVec<Attribute>)
-> P<hir::Expr> {
let id = self.next_id();
let block = P(hir::Block {
}
pub fn assign_node_ids(sess: &Session, krate: ast::Crate) -> ast::Crate {
- use syntax::codemap::Spanned;
+ use syntax::ptr::P;
+ use syntax::util::move_map::MoveMap;
+
struct NodeIdAssigner<'a> {
sess: &'a Session,
}
assert_eq!(old_id, ast::DUMMY_NODE_ID);
self.sess.next_node_id()
}
- if let Some(Spanned { node: ast::StmtKind::Expr(expr, _), span }) = stmt {
+
+ fn fold_block(&mut self, block: P<ast::Block>) -> P<ast::Block> {
+ block.map(|mut block| {
+ block.id = self.new_id(block.id);
+
+ let stmt = block.stmts.pop();
+ block.stmts = block.stmts.move_flat_map(|s| self.fold_stmt(s).into_iter());
- let id = expr.id;
- block.stmts.push(Spanned {
++ if let Some(ast::Stmt { node: ast::StmtKind::Expr(expr), span, .. }) = stmt {
+ let expr = self.fold_expr(expr);
- node: ast::StmtKind::Expr(expr, id)
++ block.stmts.push(ast::Stmt {
++ id: expr.id,
++ node: ast::StmtKind::Expr(expr),
+ span: span,
+ });
+ } else if let Some(stmt) = stmt {
+ block.stmts.extend(self.fold_stmt(stmt));
+ }
+
+ block
+ })
+ }
}
let krate = time(sess.time_passes(),
use rustc_mir::graphviz::write_mir_graphviz;
use syntax::ast::{self, BlockCheckMode};
-use syntax::codemap;
use syntax::fold::{self, Folder};
use syntax::print::{pp, pprust};
use syntax::print::pprust::PrintState;
use syntax::ptr::P;
use syntax::util::small_vector::SmallVector;
+use syntax_pos;
use graphviz as dot;
fn fold_block(&mut self, b: P<ast::Block>) -> P<ast::Block> {
fn expr_to_block(rules: ast::BlockCheckMode, e: Option<P<ast::Expr>>) -> P<ast::Block> {
P(ast::Block {
- expr: e,
- stmts: vec![],
- stmts: e.map(|e| codemap::Spanned {
++ stmts: e.map(|e| ast::Stmt {
++ id: ast::DUMMY_NODE_ID,
+ span: e.span,
- node: ast::StmtKind::Expr(e, ast::DUMMY_NODE_ID),
++ node: ast::StmtKind::Expr(e),
+ }).into_iter().collect(),
rules: rules,
id: ast::DUMMY_NODE_ID,
- span: codemap::DUMMY_SP,
+ span: syntax_pos::DUMMY_SP,
})
}
let loop_expr = P(ast::Expr {
node: ast::ExprKind::Loop(empty_block, None),
id: ast::DUMMY_NODE_ID,
- span: codemap::DUMMY_SP,
- attrs: None,
+ span: syntax_pos::DUMMY_SP,
+ attrs: ast::ThinVec::new(),
});
expr_to_block(b.rules, Some(loop_expr))
pub use self::UnsafeSource::*;
pub use self::ViewPath_::*;
pub use self::PathParameters::*;
+pub use util::ThinVec;
-use attr::{ThinAttributes, HasAttrs};
-use codemap::{mk_sp, respan, Span, Spanned, DUMMY_SP, ExpnId};
+use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
+use codemap::{respan, Spanned};
use abi::Abi;
use errors;
-use ext::base;
-use ext::tt::macro_parser;
use parse::token::{self, keywords, InternedString};
-use parse::lexer;
-use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use print::pprust;
use ptr::P;
+use tokenstream::{TokenTree};
use std::fmt;
use std::rc::Rc;
-use std::borrow::Cow;
use std::hash::{Hash, Hasher};
use serialize::{Encodable, Decodable, Encoder, Decoder};
}
}
-/// A lifetime definition, eg `'a: 'b+'c+'d`
+/// A lifetime definition, e.g. `'a: 'b+'c+'d`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct LifetimeDef {
pub lifetime: Lifetime,
pub bounds: Vec<Lifetime>
}
-/// A "Path" is essentially Rust's notion of a name; for instance:
-/// std::cmp::PartialEq . It's represented as a sequence of identifiers,
+/// A "Path" is essentially Rust's notion of a name.
+///
+/// It's represented as a sequence of identifiers,
/// along with a bunch of supporting information.
+///
+/// E.g. `std::cmp::PartialEq`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Path {
pub span: Span,
}
}
-/// A segment of a path: an identifier, an optional lifetime, and a set of
-/// types.
+/// A segment of a path: an identifier, an optional lifetime, and a set of types.
+///
+/// E.g. `std`, `String` or `Box<T>`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct PathSegment {
/// The identifier portion of this path segment.
pub parameters: PathParameters,
}
+/// Parameters of a path segment.
+///
+/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum PathParameters {
/// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
/// The type parameters for this path segment, if present.
pub types: P<[P<Ty>]>,
/// Bindings (equality constraints) on associated types, if present.
- /// e.g., `Foo<A=Bar>`.
+ ///
+ /// E.g., `Foo<A=Bar>`.
pub bindings: P<[TypeBinding]>,
}
EqPredicate(WhereEqPredicate),
}
-/// A type bound, e.g. `for<'c> Foo: Send+Clone+'c`
+/// A type bound.
+///
+/// E.g. `for<'c> Foo: Send+Clone+'c`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct WhereBoundPredicate {
pub span: Span,
pub bounds: TyParamBounds,
}
-/// A lifetime predicate, e.g. `'a: 'b+'c`
+/// A lifetime predicate.
+///
+/// E.g. `'a: 'b+'c`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct WhereRegionPredicate {
pub span: Span,
pub bounds: Vec<Lifetime>,
}
-/// An equality predicate (unsupported), e.g. `T=int`
+/// An equality predicate (unsupported).
+///
+/// E.g. `T=int`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct WhereEqPredicate {
pub id: NodeId,
pub exported_macros: Vec<MacroDef>,
}
+/// A spanned compile-time attribute item.
+///
+/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
pub type MetaItem = Spanned<MetaItemKind>;
+/// A compile-time attribute item.
+///
+/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum MetaItemKind {
+ /// Word meta item.
+ ///
+ /// E.g. `test` as in `#[test]`
Word(InternedString),
+ /// List meta item.
+ ///
+ /// E.g. `derive(..)` as in `#[derive(..)]`
List(InternedString, Vec<P<MetaItem>>),
+ /// Name value meta item.
+ ///
+ /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
NameValue(InternedString, Lit),
}
}
}
+/// A Block (`{ .. }`).
+///
+/// E.g. `{ .. }` as in `fn foo() { .. }`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Block {
/// Statements in a block
pub stmts: Vec<Stmt>,
- /// An expression at the end of the block
- /// without a semicolon, if any
- pub expr: Option<P<Expr>>,
pub id: NodeId,
/// Distinguishes between `unsafe { ... }` and `{ ... }`
pub rules: BlockCheckMode,
PatKind::Range(_, _) |
PatKind::Ident(_, _, _) |
PatKind::Path(..) |
- PatKind::QPath(_, _) |
PatKind::Mac(_) => {
true
}
/// 0 <= position <= subpats.len()
TupleStruct(Path, Vec<P<Pat>>, Option<usize>),
- /// A path pattern.
- /// Such pattern can be resolved to a unit struct/variant or a constant.
- Path(Path),
-
- /// An associated const named using the qualified path `<T>::CONST` or
- /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
- /// referred to as simply `T::CONST`, in which case they will end up as
- /// PatKind::Path, and the resolver will have to sort that out.
- QPath(QSelf, Path),
+ /// A possibly qualified path pattern.
+ /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
+ /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
+ /// only legally refer to associated constants.
+ Path(Option<QSelf>, Path),
/// A tuple pattern `(a, b)`.
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
}
/// A statement
-pub type Stmt = Spanned<StmtKind>;
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
+pub struct Stmt {
+ pub id: NodeId,
+ pub node: StmtKind,
+ pub span: Span,
+}
impl fmt::Debug for Stmt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "stmt({}: {})",
- self.node.id()
- .map_or(Cow::Borrowed("<macro>"),|id|Cow::Owned(id.to_string())),
- pprust::stmt_to_string(self))
+ write!(f, "stmt({}: {})", self.id.to_string(), pprust::stmt_to_string(self))
}
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub enum StmtKind {
- /// Could be an item or a local (let) binding:
- Decl(P<Decl>, NodeId),
+ /// A local (let) binding.
+ Local(P<Local>),
- /// Expr without trailing semi-colon
- Expr(P<Expr>, NodeId),
+ /// An item definition.
+ Item(P<Item>),
- /// Expr without trailing semi-colon (must have unit type).
- /// Expr with trailing semi-colon (may have any type):
- Semi(P<Expr>, NodeId),
++ /// Expr without trailing semi-colon.
+ Expr(P<Expr>),
- Mac(P<Mac>, MacStmtStyle, ThinAttributes),
-}
+ Semi(P<Expr>),
-impl StmtKind {
- pub fn id(&self) -> Option<NodeId> {
- match *self {
- StmtKind::Decl(_, id) => Some(id),
- StmtKind::Expr(_, id) => Some(id),
- StmtKind::Semi(_, id) => Some(id),
- StmtKind::Mac(..) => None,
- }
- }
-
- pub fn attrs(&self) -> &[Attribute] {
- HasAttrs::attrs(self)
- }
+ Mac(P<(Mac, MacStmtStyle, ThinVec<Attribute>)>),
}
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub init: Option<P<Expr>>,
pub id: NodeId,
pub span: Span,
- pub attrs: ThinAttributes,
-}
-
-impl Local {
- pub fn attrs(&self) -> &[Attribute] {
- HasAttrs::attrs(self)
- }
+ pub attrs: ThinVec<Attribute>,
}
-pub type Decl = Spanned<DeclKind>;
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum DeclKind {
- /// A local (let) binding:
- Local(P<Local>),
- /// An item binding:
- Item(P<Item>),
-}
-
-impl Decl {
- pub fn attrs(&self) -> &[Attribute] {
- HasAttrs::attrs(self)
- }
-}
-
-/// represents one arm of a 'match'
+/// An arm of a 'match'.
+///
+/// E.g. `0...10 => { println!("match!") }` as in
+///
+/// ```rust,ignore
+/// match n {
+/// 0...10 => { println!("match!") },
+/// // ..
+/// }
+/// ```
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Arm {
pub attrs: Vec<Attribute>,
pub id: NodeId,
pub node: ExprKind,
pub span: Span,
- pub attrs: ThinAttributes
-}
-
-impl Expr {
- pub fn attrs(&self) -> &[Attribute] {
- HasAttrs::attrs(self)
- }
+ pub attrs: ThinVec<Attribute>
}
impl fmt::Debug for Expr {
/// parameters, e.g. foo::bar::<baz>.
///
/// Optionally "qualified",
- /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
+ /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
Path(Option<QSelf>, Path),
/// A referencing operation (`&a` or `&mut a`)
/// A `break`, with an optional label to break
Break(Option<SpannedIdent>),
/// A `continue`, with an optional label
- Again(Option<SpannedIdent>),
+ Continue(Option<SpannedIdent>),
/// A `return`, with an optional value to be returned
Ret(Option<P<Expr>>),
/// separately. `position` represents the index of the associated
/// item qualified with this Self type.
///
-/// ```ignore
+/// ```rust,ignore
/// <Vec<T> as a::b::Trait>::AssociatedItem
/// ^~~~~ ~~~~~~~~~~~~~~^
/// ty position = 3
Ref,
}
-/// A delimited sequence of token trees
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Delimited {
- /// The type of delimiter
- pub delim: token::DelimToken,
- /// The span covering the opening delimiter
- pub open_span: Span,
- /// The delimited sequence of token trees
- pub tts: Vec<TokenTree>,
- /// The span covering the closing delimiter
- pub close_span: Span,
-}
-
-impl Delimited {
- /// Returns the opening delimiter as a token.
- pub fn open_token(&self) -> token::Token {
- token::OpenDelim(self.delim)
- }
-
- /// Returns the closing delimiter as a token.
- pub fn close_token(&self) -> token::Token {
- token::CloseDelim(self.delim)
- }
-
- /// Returns the opening delimiter as a token tree.
- pub fn open_tt(&self) -> TokenTree {
- TokenTree::Token(self.open_span, self.open_token())
- }
-
- /// Returns the closing delimiter as a token tree.
- pub fn close_tt(&self) -> TokenTree {
- TokenTree::Token(self.close_span, self.close_token())
- }
-}
-
-/// A sequence of token trees
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct SequenceRepetition {
- /// The sequence of token trees
- pub tts: Vec<TokenTree>,
- /// The optional separator
- pub separator: Option<token::Token>,
- /// Whether the sequence can be repeated zero (*), or one or more times (+)
- pub op: KleeneOp,
- /// The number of `MatchNt`s that appear in the sequence (and subsequences)
- pub num_captures: usize,
-}
-
-/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
-/// for token sequences.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum KleeneOp {
- ZeroOrMore,
- OneOrMore,
-}
-
-/// When the main rust parser encounters a syntax-extension invocation, it
-/// parses the arguments to the invocation as a token-tree. This is a very
-/// loose structure, such that all sorts of different AST-fragments can
-/// be passed to syntax extensions using a uniform type.
-///
-/// If the syntax extension is an MBE macro, it will attempt to match its
-/// LHS token tree against the provided token tree, and if it finds a
-/// match, will transcribe the RHS token tree, splicing in any captured
-/// macro_parser::matched_nonterminals into the `SubstNt`s it finds.
-///
-/// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
-/// Nothing special happens to misnamed or misplaced `SubstNt`s.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TokenTree {
- /// A single token
- Token(Span, token::Token),
- /// A delimited sequence of token trees
- Delimited(Span, Rc<Delimited>),
-
- // This only makes sense in MBE macros.
-
- /// A kleene-style repetition sequence with a span
- // FIXME(eddyb) #12938 Use DST.
- Sequence(Span, Rc<SequenceRepetition>),
-}
-
-impl TokenTree {
- pub fn len(&self) -> usize {
- match *self {
- TokenTree::Token(_, token::DocComment(name)) => {
- match doc_comment_style(&name.as_str()) {
- AttrStyle::Outer => 2,
- AttrStyle::Inner => 3
- }
- }
- TokenTree::Token(_, token::SpecialVarNt(..)) => 2,
- TokenTree::Token(_, token::MatchNt(..)) => 3,
- TokenTree::Delimited(_, ref delimed) => {
- delimed.tts.len() + 2
- }
- TokenTree::Sequence(_, ref seq) => {
- seq.tts.len()
- }
- TokenTree::Token(..) => 0
- }
- }
-
- pub fn get_tt(&self, index: usize) -> TokenTree {
- match (self, index) {
- (&TokenTree::Token(sp, token::DocComment(_)), 0) => {
- TokenTree::Token(sp, token::Pound)
- }
- (&TokenTree::Token(sp, token::DocComment(name)), 1)
- if doc_comment_style(&name.as_str()) == AttrStyle::Inner => {
- TokenTree::Token(sp, token::Not)
- }
- (&TokenTree::Token(sp, token::DocComment(name)), _) => {
- let stripped = strip_doc_comment_decoration(&name.as_str());
-
- // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
- // required to wrap the text.
- let num_of_hashes = stripped.chars().scan(0, |cnt, x| {
- *cnt = if x == '"' {
- 1
- } else if *cnt != 0 && x == '#' {
- *cnt + 1
- } else {
- 0
- };
- Some(*cnt)
- }).max().unwrap_or(0);
-
- TokenTree::Delimited(sp, Rc::new(Delimited {
- delim: token::Bracket,
- open_span: sp,
- tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc"))),
- TokenTree::Token(sp, token::Eq),
- TokenTree::Token(sp, token::Literal(
- token::StrRaw(token::intern(&stripped), num_of_hashes), None))],
- close_span: sp,
- }))
- }
- (&TokenTree::Delimited(_, ref delimed), _) => {
- if index == 0 {
- return delimed.open_tt();
- }
- if index == delimed.tts.len() + 1 {
- return delimed.close_tt();
- }
- delimed.tts[index - 1].clone()
- }
- (&TokenTree::Token(sp, token::SpecialVarNt(var)), _) => {
- let v = [TokenTree::Token(sp, token::Dollar),
- TokenTree::Token(sp, token::Ident(token::str_to_ident(var.as_str())))];
- v[index].clone()
- }
- (&TokenTree::Token(sp, token::MatchNt(name, kind)), _) => {
- let v = [TokenTree::Token(sp, token::SubstNt(name)),
- TokenTree::Token(sp, token::Colon),
- TokenTree::Token(sp, token::Ident(kind))];
- v[index].clone()
- }
- (&TokenTree::Sequence(_, ref seq), _) => {
- seq.tts[index].clone()
- }
- _ => panic!("Cannot expand a token tree")
- }
- }
-
- /// Returns the `Span` corresponding to this token tree.
- pub fn get_span(&self) -> Span {
- match *self {
- TokenTree::Token(span, _) => span,
- TokenTree::Delimited(span, _) => span,
- TokenTree::Sequence(span, _) => span,
- }
- }
-
- /// Use this token tree as a matcher to parse given tts.
- pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree])
- -> macro_parser::NamedParseResult {
- // `None` is because we're not interpolating
- let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
- None,
- None,
- tts.iter().cloned().collect(),
- true);
- macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch)
- }
-}
-
pub type Mac = Spanned<Mac_>;
/// Represents a macro invocation. The Path indicates which macro
pub struct Mac_ {
pub path: Path,
pub tts: Vec<TokenTree>,
- pub ctxt: SyntaxContext,
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
Unsuffixed,
}
+/// Literal kind.
+///
+/// E.g. `"foo"`, `42`, `12.34` or `bool`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum LitKind {
/// A string literal (`"foo"`)
Const(P<Ty>, Option<P<Expr>>),
Method(MethodSig, Option<P<Block>>),
Type(TyParamBounds, Option<P<Ty>>),
+ Macro(Mac),
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub decl: P<FnDecl>
}
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
/// The different kinds of types recognized by the compiler
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum TyKind {
Vec(P<Ty>),
/// A fixed length array (`[T; n]`)
Mac(Mac),
}
+/// Inline assembly dialect.
+///
+/// E.g. `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")``
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum AsmDialect {
Att,
Intel,
}
+/// Inline assembly.
+///
+/// E.g. `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")``
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsmOutput {
pub constraint: InternedString,
pub is_indirect: bool,
}
+/// Inline assembly.
+///
+/// E.g. `asm!("NOP");`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsm {
pub asm: InternedString,
pub expn_id: ExpnId,
}
-/// represents an argument in a function header
+/// An argument in a function header.
+///
+/// E.g. `bar: usize` as in `fn foo(bar: usize)`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Arg {
pub ty: P<Ty>,
}
/// Alternative representation for `Arg`s describing `self` parameter of methods.
+///
+/// E.g. `&mut self` as in `fn foo(&mut self)`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum SelfKind {
/// `self`, `mut self`
}
}
-/// Represents the header (not the body) of a function declaration
+/// Header (not the body) of a function declaration.
+///
+/// E.g. `fn foo(bar: baz)`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct FnDecl {
pub inputs: Vec<Arg>,
}
}
+/// Module declaration.
+///
+/// E.g. `mod foo;` or `mod foo { .. }`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Mod {
/// A span from the first token past `{` to the last token until `}`.
pub items: Vec<P<Item>>,
}
+/// Foreign module declaration.
+///
+/// E.g. `extern { .. }` or `extern C { .. }`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct ForeignMod {
pub abi: Abi,
pub name: Ident,
pub attrs: Vec<Attribute>,
pub data: VariantData,
- /// Explicit discriminant, eg `Foo = 1`
+ /// Explicit discriminant, e.g. `Foo = 1`
pub disr_expr: Option<P<Expr>>,
}
pub enum PathListItemKind {
Ident {
name: Ident,
- /// renamed in list, eg `use foo::{bar as baz};`
+ /// renamed in list, e.g. `use foo::{bar as baz};`
rename: Option<Ident>,
id: NodeId
},
Mod {
- /// renamed in list, eg `use foo::{self as baz};`
+ /// renamed in list, e.g. `use foo::{self as baz};`
rename: Option<Ident>,
id: NodeId
}
Inherited,
}
+/// Field of a struct.
+///
+/// E.g. `bar: usize` as in `struct Foo { bar: usize }`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct StructField {
pub span: Span,
/// Id of the whole struct lives in `Item`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum VariantData {
+ /// Struct variant.
+ ///
+ /// E.g. `Bar { .. }` as in `enum Foo { Bar { .. } }`
Struct(Vec<StructField>, NodeId),
+ /// Tuple variant.
+ ///
+ /// E.g. `Bar(..)` as in `enum Foo { Bar(..) }`
Tuple(Vec<StructField>, NodeId),
+ /// Unit variant.
+ ///
+ /// E.g. `Bar = ..` as in `enum Foo { Bar = .. }`
Unit(NodeId),
}
pub span: Span,
}
-impl Item {
- pub fn attrs(&self) -> &[Attribute] {
- &self.attrs
- }
-}
-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum ItemKind {
- /// An`extern crate` item, with optional original crate name,
+ /// An`extern crate` item, with optional original crate name.
///
- /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
+ /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
ExternCrate(Option<Name>),
- /// A `use` or `pub use` item
+ /// A use declaration (`use` or `pub use`) item.
+ ///
+ /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
Use(P<ViewPath>),
-
- /// A `static` item
+ /// A static item (`static` or `pub static`).
+ ///
+ /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
Static(P<Ty>, Mutability, P<Expr>),
- /// A `const` item
+ /// A constant item (`const` or `pub const`).
+ ///
+ /// E.g. `const FOO: i32 = 42;`
Const(P<Ty>, P<Expr>),
- /// A function declaration
+ /// A function declaration (`fn` or `pub fn`).
+ ///
+ /// E.g. `fn foo(bar: usize) -> usize { .. }`
Fn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
- /// A module
+ /// A module declaration (`mod` or `pub mod`).
+ ///
+ /// E.g. `mod foo;` or `mod foo { .. }`
Mod(Mod),
- /// An external module
+ /// An external module (`extern` or `pub extern`).
+ ///
+ /// E.g. `extern {}` or `extern "C" {}`
ForeignMod(ForeignMod),
- /// A type alias, e.g. `type Foo = Bar<u8>`
+ /// A type alias (`type` or `pub type`).
+ ///
+ /// E.g. `type Foo = Bar<u8>;`
Ty(P<Ty>, Generics),
- /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
+ /// An enum definition (`enum` or `pub enum`).
+ ///
+ /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
Enum(EnumDef, Generics),
- /// A struct definition, e.g. `struct Foo<A> {x: A}`
+ /// A struct definition (`struct` or `pub struct`).
+ ///
+ /// E.g. `struct Foo<A> { x: A }`
Struct(VariantData, Generics),
- /// Represents a Trait Declaration
+ /// A Trait declaration (`trait` or `pub trait`).
+ ///
+ /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
Trait(Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
-
- // Default trait implementations
+ // Default trait implementation.
///
- // `impl Trait for .. {}`
+ /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
DefaultImpl(Unsafety, TraitRef),
- /// An implementation, eg `impl<A> Trait for Foo { .. }`
+ /// An implementation.
+ ///
+ /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
Impl(Unsafety,
ImplPolarity,
Generics,
Option<TraitRef>, // (optional) trait this impl implements
P<Ty>, // self
Vec<ImplItem>),
- /// A macro invocation (which includes macro definition)
+ /// A macro invocation (which includes macro definition).
+ ///
+ /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
Mac(Mac),
}
use abi::Abi;
use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind};
use attr;
-use codemap::{Span, respan, Spanned, DUMMY_SP, Pos};
+use syntax_pos::{Span, DUMMY_SP, Pos};
+use codemap::{respan, Spanned};
use ext::base::ExtCtxt;
use parse::token::{self, keywords, InternedString};
use ptr::P;
// statements
fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt;
+ fn stmt_semi(&self, expr: P<ast::Expr>) -> ast::Stmt;
fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P<ast::Expr>) -> ast::Stmt;
fn stmt_let_typed(&self,
sp: Span,
fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt;
// blocks
- fn block(&self, span: Span, stmts: Vec<ast::Stmt>,
- expr: Option<P<ast::Expr>>) -> P<ast::Block>;
+ fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block>;
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>;
- fn block_all(&self, span: Span,
- stmts: Vec<ast::Stmt>,
- expr: Option<P<ast::Expr>>) -> P<ast::Block>;
// expressions
fn expr(&self, span: Span, node: ast::ExprKind) -> P<ast::Expr>;
}
fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt {
- respan(expr.span, ast::StmtKind::Expr(expr, ast::DUMMY_NODE_ID))
++ ast::Stmt {
++ id: ast::DUMMY_NODE_ID,
++ span: expr.span,
++ node: ast::StmtKind::Expr(expr),
++ }
+ }
+
+ fn stmt_semi(&self, expr: P<ast::Expr>) -> ast::Stmt {
- respan(expr.span, ast::StmtKind::Semi(expr, ast::DUMMY_NODE_ID))
+ ast::Stmt {
+ id: ast::DUMMY_NODE_ID,
+ span: expr.span,
+ node: ast::StmtKind::Semi(expr),
+ }
}
fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident,
init: Some(ex),
id: ast::DUMMY_NODE_ID,
span: sp,
- attrs: None,
+ attrs: ast::ThinVec::new(),
});
- let decl = respan(sp, ast::DeclKind::Local(local));
- respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))
+ ast::Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: ast::StmtKind::Local(local),
+ span: sp,
+ }
}
fn stmt_let_typed(&self,
init: Some(ex),
id: ast::DUMMY_NODE_ID,
span: sp,
- attrs: None,
+ attrs: ast::ThinVec::new(),
});
- let decl = respan(sp, ast::DeclKind::Local(local));
- P(respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID)))
+ P(ast::Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: ast::StmtKind::Local(local),
+ span: sp,
+ })
}
- fn block(&self, span: Span, stmts: Vec<ast::Stmt>,
- expr: Option<P<Expr>>) -> P<ast::Block> {
- self.block_all(span, stmts, expr)
- }
-
fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt {
- let decl = respan(sp, ast::DeclKind::Item(item));
- respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))
+ ast::Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: ast::StmtKind::Item(item),
+ span: sp,
+ }
}
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
- self.block_all(expr.span, Vec::new(), Some(expr))
- }
- fn block_all(&self,
- span: Span,
- stmts: Vec<ast::Stmt>,
- expr: Option<P<ast::Expr>>) -> P<ast::Block> {
- P(ast::Block {
- stmts: stmts,
- expr: expr,
- id: ast::DUMMY_NODE_ID,
- rules: BlockCheckMode::Default,
- span: span,
- })
- self.block(expr.span, vec![Spanned {
++ self.block(expr.span, vec![ast::Stmt {
++ id: ast::DUMMY_NODE_ID,
+ span: expr.span,
- node: ast::StmtKind::Expr(expr, ast::DUMMY_NODE_ID),
++ node: ast::StmtKind::Expr(expr),
+ }])
+ }
+ fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> {
+ P(ast::Block {
+ stmts: stmts,
+ id: ast::DUMMY_NODE_ID,
+ rules: BlockCheckMode::Default,
+ span: span,
+ })
}
fn expr(&self, span: Span, node: ast::ExprKind) -> P<ast::Expr> {
id: ast::DUMMY_NODE_ID,
node: node,
span: span,
- attrs: None,
+ attrs: ast::ThinVec::new(),
})
}
}
fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
let pat = if subpats.is_empty() {
- PatKind::Path(path)
+ PatKind::Path(None, path)
} else {
PatKind::TupleStruct(path, subpats, None)
};
ids: Vec<ast::Ident>,
stmts: Vec<ast::Stmt>)
-> P<ast::Expr> {
- self.lambda(span, ids, self.block(span, stmts, None))
+ self.lambda(span, ids, self.block(span, stmts))
}
fn lambda_stmts_0(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Expr> {
- self.lambda0(span, self.block(span, stmts, None))
+ self.lambda0(span, self.block(span, stmts))
}
fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>,
ident: ast::Ident) -> P<ast::Expr> {
- self.lambda1(span, self.block(span, stmts, None), ident)
+ self.lambda1(span, self.block(span, stmts), ident)
}
fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use ast::{Block, Crate, DeclKind, PatKind};
+use ast::{Block, Crate, PatKind};
use ast::{Local, Ident, Mac_, Name, SpannedIdent};
use ast::{MacStmtStyle, Mrk, Stmt, StmtKind, ItemKind};
-use ast::TokenTree;
use ast;
+use attr::HasAttrs;
use ext::mtwt;
-use ext::build::AstBuilder;
use attr;
-use attr::{AttrMetaMethods, WithAttrs, ThinAttributesExt};
-use codemap;
-use codemap::{Span, Spanned, ExpnInfo, ExpnId, NameAndSpan, MacroBang, MacroAttribute};
+use attr::AttrMetaMethods;
+use codemap::{Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
+use syntax_pos::{self, Span, ExpnId};
use config::StripUnconfigured;
use ext::base::*;
use feature_gate::{self, Features};
use util::move_map::MoveMap;
use parse::token::{fresh_mark, fresh_name, intern, keywords};
use ptr::P;
+use tokenstream::TokenTree;
use util::small_vector::SmallVector;
use visit;
use visit::Visitor;
// Fold this node or list of nodes using the given folder.
fn fold_with<F: Folder>(self, folder: &mut F) -> Self;
- fn visit_with<'v, V: Visitor<'v>>(&'v self, visitor: &mut V);
+ fn visit_with<V: Visitor>(&self, visitor: &mut V);
// Return a placeholder expansion to allow compilation to continue after an erroring expansion.
fn dummy(span: Span) -> Self;
$( folder.$fold(self) )*
$( self.into_iter().flat_map(|item| folder. $fold_elt (item)).collect() )*
}
- fn visit_with<'v, V: Visitor<'v>>(&'v self, visitor: &mut V) {
+ fn visit_with<V: Visitor>(&self, visitor: &mut V) {
$( visitor.$visit(self) )*
$( for item in self.as_slice() { visitor. $visit_elt (item) } )*
}
"statement", .make_stmts, lift .fold_stmt, lift .visit_stmt, |_span| SmallVector::zero();
SmallVector<P<ast::Item>>:
"item", .make_items, lift .fold_item, lift .visit_item, |_span| SmallVector::zero();
+ SmallVector<ast::TraitItem>:
+ "trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item,
+ |_span| SmallVector::zero();
SmallVector<ast::ImplItem>:
- "impl item", .make_impl_items, lift .fold_impl_item, lift .visit_impl_item,
+ "impl item", .make_impl_items, lift .fold_impl_item, lift .visit_impl_item,
|_span| SmallVector::zero();
}
fn fold_with<F: Folder>(self, folder: &mut F) -> Self {
self.and_then(|expr| folder.fold_opt_expr(expr))
}
- fn visit_with<'v, V: Visitor<'v>>(&'v self, visitor: &mut V) {
+ fn visit_with<V: Visitor>(&self, visitor: &mut V) {
self.as_ref().map(|expr| visitor.visit_expr(expr));
}
}
-pub fn expand_expr(expr: ast::Expr, fld: &mut MacroExpander) -> P<ast::Expr> {
+pub fn expand_expr(mut expr: ast::Expr, fld: &mut MacroExpander) -> P<ast::Expr> {
match expr.node {
// expr_mac should really be expr_ext or something; it's the
// entry-point for all syntax extensions.
ast::ExprKind::Mac(mac) => {
- expand_mac_invoc(mac, None, expr.attrs.into_attr_vec(), expr.span, fld)
+ return expand_mac_invoc(mac, None, expr.attrs.into(), expr.span, fld);
}
ast::ExprKind::While(cond, body, opt_ident) => {
let cond = fld.fold_expr(cond);
let (body, opt_ident) = expand_loop_block(body, opt_ident, fld);
- fld.cx.expr(expr.span, ast::ExprKind::While(cond, body, opt_ident))
- .with_attrs(fold_thin_attrs(expr.attrs, fld))
+ expr.node = ast::ExprKind::While(cond, body, opt_ident);
}
ast::ExprKind::WhileLet(pat, cond, body, opt_ident) => {
});
assert!(rewritten_pats.len() == 1);
- let wl = ast::ExprKind::WhileLet(rewritten_pats.remove(0), cond, body, opt_ident);
- fld.cx.expr(expr.span, wl).with_attrs(fold_thin_attrs(expr.attrs, fld))
+ expr.node = ast::ExprKind::WhileLet(rewritten_pats.remove(0), cond, body, opt_ident);
}
ast::ExprKind::Loop(loop_block, opt_ident) => {
let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld);
- fld.cx.expr(expr.span, ast::ExprKind::Loop(loop_block, opt_ident))
- .with_attrs(fold_thin_attrs(expr.attrs, fld))
+ expr.node = ast::ExprKind::Loop(loop_block, opt_ident);
}
ast::ExprKind::ForLoop(pat, head, body, opt_ident) => {
assert!(rewritten_pats.len() == 1);
let head = fld.fold_expr(head);
- let fl = ast::ExprKind::ForLoop(rewritten_pats.remove(0), head, body, opt_ident);
- fld.cx.expr(expr.span, fl).with_attrs(fold_thin_attrs(expr.attrs, fld))
+ expr.node = ast::ExprKind::ForLoop(rewritten_pats.remove(0), head, body, opt_ident);
}
ast::ExprKind::IfLet(pat, sub_expr, body, else_opt) => {
let else_opt = else_opt.map(|else_opt| fld.fold_expr(else_opt));
let sub_expr = fld.fold_expr(sub_expr);
- let il = ast::ExprKind::IfLet(rewritten_pats.remove(0), sub_expr, body, else_opt);
- fld.cx.expr(expr.span, il).with_attrs(fold_thin_attrs(expr.attrs, fld))
+ expr.node = ast::ExprKind::IfLet(rewritten_pats.remove(0), sub_expr, body, else_opt);
}
ast::ExprKind::Closure(capture_clause, fn_decl, block, fn_decl_span) => {
let (rewritten_fn_decl, rewritten_block)
= expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
- let new_node = ast::ExprKind::Closure(capture_clause,
- rewritten_fn_decl,
- rewritten_block,
- fn_decl_span);
- P(ast::Expr{ id: expr.id,
- node: new_node,
- span: expr.span,
- attrs: fold_thin_attrs(expr.attrs, fld) })
+ expr.node = ast::ExprKind::Closure(capture_clause,
+ rewritten_fn_decl,
+ rewritten_block,
+ fn_decl_span);
}
- _ => P(noop_fold_expr(expr, fld)),
- }
+ _ => expr = noop_fold_expr(expr, fld),
+ };
+ P(expr)
}
/// Expand a macro invocation. Returns the result of expansion.
},
});
- let marked_tts = mark_tts(&tts[..], mark);
+ let marked_tts = mark_tts(tts, mark);
Some(expandfun.expand(fld.cx, call_site, &marked_tts))
}
}
});
- let marked_tts = mark_tts(&tts, mark);
+ let marked_tts = mark_tts(tts, mark);
Some(expander.expand(fld.cx, call_site, ident, marked_tts))
}
};
let (mac, style, attrs) = match stmt.node {
- StmtKind::Mac(mac, style, attrs) => (mac, style, attrs),
+ StmtKind::Mac(mac) => mac.unwrap(),
_ => return expand_non_macro_stmt(stmt, fld)
};
let mut fully_expanded: SmallVector<ast::Stmt> =
- expand_mac_invoc(mac.unwrap(), None, attrs.into_attr_vec(), stmt.span, fld);
+ expand_mac_invoc(mac, None, attrs.into(), stmt.span, fld);
// If this is a macro invocation with a semicolon, then apply that
// semicolon to the final statement produced by expansion.
if style == MacStmtStyle::Semicolon {
if let Some(stmt) = fully_expanded.pop() {
- let new_stmt = Spanned {
+ fully_expanded.push(Stmt {
+ id: stmt.id,
node: match stmt.node {
- StmtKind::Expr(e, stmt_id) => StmtKind::Semi(e, stmt_id),
+ StmtKind::Expr(expr) => StmtKind::Semi(expr),
_ => stmt.node /* might already have a semi */
},
- span: stmt.span
- };
- fully_expanded.push(new_stmt);
+ span: stmt.span,
+ });
}
}
// expand a non-macro stmt. this is essentially the fallthrough for
// expand_stmt, above.
-fn expand_non_macro_stmt(Spanned {node, span: stmt_span}: Stmt, fld: &mut MacroExpander)
+fn expand_non_macro_stmt(stmt: Stmt, fld: &mut MacroExpander)
-> SmallVector<Stmt> {
// is it a let?
- match node {
- StmtKind::Decl(decl, node_id) => decl.and_then(|Spanned {node: decl, span}| match decl {
- DeclKind::Local(local) => {
- // take it apart:
- let rewritten_local = local.map(|Local {id, pat, ty, init, span, attrs}| {
- // expand the ty since TyKind::FixedLengthVec contains an Expr
- // and thus may have a macro use
- let expanded_ty = ty.map(|t| fld.fold_ty(t));
- // expand the pat (it might contain macro uses):
- let expanded_pat = fld.fold_pat(pat);
- // find the PatIdents in the pattern:
- // oh dear heaven... this is going to include the enum
- // names, as well... but that should be okay, as long as
- // the new names are gensyms for the old ones.
- // generate fresh names, push them to a new pending list
- let idents = pattern_bindings(&expanded_pat);
- let mut new_pending_renames =
- idents.iter().map(|ident| (*ident, fresh_name(*ident))).collect();
- // rewrite the pattern using the new names (the old
- // ones have already been applied):
- let rewritten_pat = {
- // nested binding to allow borrow to expire:
- let mut rename_fld = IdentRenamer{renames: &mut new_pending_renames};
- rename_fld.fold_pat(expanded_pat)
- };
- // add them to the existing pending renames:
- fld.cx.syntax_env.info().pending_renames
- .extend(new_pending_renames);
- Local {
- id: id,
- ty: expanded_ty,
- pat: rewritten_pat,
- // also, don't forget to expand the init:
- init: init.map(|e| fld.fold_expr(e)),
- span: span,
- attrs: fold::fold_thin_attrs(attrs, fld),
- }
- });
- SmallVector::one(Spanned {
- node: StmtKind::Decl(P(Spanned {
- node: DeclKind::Local(rewritten_local),
- span: span
- }),
- node_id),
- span: stmt_span
- })
- }
- _ => {
- noop_fold_stmt(Spanned {
- node: StmtKind::Decl(P(Spanned {
- node: decl,
- span: span
- }),
- node_id),
- span: stmt_span
- }, fld)
- }
- }),
- _ => {
- noop_fold_stmt(Spanned {
- node: node,
- span: stmt_span
- }, fld)
+ match stmt.node {
+ StmtKind::Local(local) => {
+ // take it apart:
+ let rewritten_local = local.map(|Local {id, pat, ty, init, span, attrs}| {
+ // expand the ty since TyKind::FixedLengthVec contains an Expr
+ // and thus may have a macro use
+ let expanded_ty = ty.map(|t| fld.fold_ty(t));
+ // expand the pat (it might contain macro uses):
+ let expanded_pat = fld.fold_pat(pat);
+ // find the PatIdents in the pattern:
+ // oh dear heaven... this is going to include the enum
+ // names, as well... but that should be okay, as long as
+ // the new names are gensyms for the old ones.
+ // generate fresh names, push them to a new pending list
+ let idents = pattern_bindings(&expanded_pat);
+ let mut new_pending_renames =
+ idents.iter().map(|ident| (*ident, fresh_name(*ident))).collect();
+ // rewrite the pattern using the new names (the old
+ // ones have already been applied):
+ let rewritten_pat = {
+ // nested binding to allow borrow to expire:
+ let mut rename_fld = IdentRenamer{renames: &mut new_pending_renames};
+ rename_fld.fold_pat(expanded_pat)
+ };
+ // add them to the existing pending renames:
+ fld.cx.syntax_env.info().pending_renames
+ .extend(new_pending_renames);
+ Local {
+ id: id,
+ ty: expanded_ty,
+ pat: rewritten_pat,
+ // also, don't forget to expand the init:
+ init: init.map(|e| fld.fold_expr(e)),
+ span: span,
+ attrs: fold::fold_thin_attrs(attrs, fld),
+ }
+ });
+ SmallVector::one(Stmt {
+ id: stmt.id,
+ node: StmtKind::Local(rewritten_local),
+ span: stmt.span,
+ })
}
+ _ => noop_fold_stmt(stmt, fld),
}
}
ident_accumulator: Vec<ast::Ident>
}
-impl<'v> Visitor<'v> for PatIdentFinder {
+impl Visitor for PatIdentFinder {
fn visit_pat(&mut self, pattern: &ast::Pat) {
match *pattern {
ast::Pat { id: _, node: PatKind::Ident(_, ref path1, ref inner), span: _ } => {
// expand the elements of a block.
pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
- b.map(|Block {id, stmts, expr, rules, span}| {
+ b.map(|Block {id, stmts, rules, span}| {
let new_stmts = stmts.into_iter().flat_map(|x| {
// perform pending renames and expand macros in the statement
fld.fold_stmt(x).into_iter()
}).collect();
- let new_expr = expr.map(|x| {
- let expr = {
- let pending_renames = &mut fld.cx.syntax_env.info().pending_renames;
- let mut rename_fld = IdentRenamer{renames:pending_renames};
- rename_fld.fold_expr(x)
- };
- fld.fold_expr(expr)
- });
Block {
id: fld.new_id(id),
stmts: new_stmts,
- expr: new_expr,
rules: rules,
span: span
}
}
}
-fn expand_annotatable(a: Annotatable,
- fld: &mut MacroExpander)
- -> SmallVector<Annotatable> {
- let a = expand_item_multi_modifier(a, fld);
-
+fn expand_multi_modified(a: Annotatable, fld: &mut MacroExpander) -> SmallVector<Annotatable> {
let new_items: SmallVector<Annotatable> = match a {
Annotatable::Item(it) => match it.node {
ast::ItemKind::Mac(..) => {
_ => noop_fold_item(it, fld),
}.into_iter().map(|i| Annotatable::Item(i)).collect(),
- Annotatable::TraitItem(it) => match it.node {
- ast::TraitItemKind::Method(_, Some(_)) => {
- let ti = it.unwrap();
- SmallVector::one(ast::TraitItem {
- id: ti.id,
- ident: ti.ident,
- attrs: ti.attrs,
- node: match ti.node {
- ast::TraitItemKind::Method(sig, Some(body)) => {
- let (sig, body) = expand_and_rename_method(sig, body, fld);
- ast::TraitItemKind::Method(sig, Some(body))
- }
- _ => unreachable!()
- },
- span: ti.span,
- })
- }
- _ => fold::noop_fold_trait_item(it.unwrap(), fld)
- }.into_iter().map(|ti| Annotatable::TraitItem(P(ti))).collect(),
+ Annotatable::TraitItem(it) => {
+ expand_trait_item(it.unwrap(), fld).into_iter().
+ map(|it| Annotatable::TraitItem(P(it))).collect()
+ }
Annotatable::ImplItem(ii) => {
expand_impl_item(ii.unwrap(), fld).into_iter().
new_items
}
-// Partition a set of attributes into one kind of attribute, and other kinds.
-macro_rules! partition {
- ($fn_name: ident, $variant: ident) => {
- #[allow(deprecated)] // The `allow` is needed because the `Modifier` variant might be used.
- fn $fn_name(attrs: &[ast::Attribute],
- fld: &MacroExpander)
- -> (Vec<ast::Attribute>, Vec<ast::Attribute>) {
- attrs.iter().cloned().partition(|attr| {
- match fld.cx.syntax_env.find(intern(&attr.name())) {
- Some(rc) => match *rc {
- $variant(..) => true,
- _ => false
- },
- _ => false
- }
- })
- }
- }
-}
-
-partition!(multi_modifiers, MultiModifier);
-
-
fn expand_decorators(a: Annotatable,
fld: &mut MacroExpander,
decorator_items: &mut SmallVector<Annotatable>,
}
}
-fn expand_item_multi_modifier(mut it: Annotatable,
- fld: &mut MacroExpander)
- -> Annotatable {
- let (modifiers, other_attrs) = multi_modifiers(it.attrs(), fld);
-
- // Update the attrs, leave everything else alone. Is this mutation really a good idea?
- it = it.fold_attrs(other_attrs);
-
- if modifiers.is_empty() {
- return it
- }
-
- for attr in &modifiers {
- let mname = intern(&attr.name());
-
- match fld.cx.syntax_env.find(mname) {
- Some(rc) => match *rc {
- MultiModifier(ref mac) => {
- attr::mark_used(attr);
- fld.cx.bt_push(ExpnInfo {
- call_site: attr.span,
- callee: NameAndSpan {
- format: MacroAttribute(mname),
- span: Some(attr.span),
- // attributes can do whatever they like,
- // for now
- allow_internal_unstable: true,
- }
- });
- it = mac.expand(fld.cx, attr.span, &attr.node.value, it);
- fld.cx.bt_pop();
+fn expand_annotatable(mut item: Annotatable, fld: &mut MacroExpander) -> SmallVector<Annotatable> {
+ let mut multi_modifier = None;
+ item = item.map_attrs(|mut attrs| {
+ for i in 0..attrs.len() {
+ if let Some(extension) = fld.cx.syntax_env.find(intern(&attrs[i].name())) {
+ if let MultiModifier(..) = *extension {
+ multi_modifier = Some((attrs.remove(i), extension));
+ break;
}
- _ => unreachable!()
- },
- _ => unreachable!()
+ }
}
- }
+ attrs
+ });
- // Expansion may have added new ItemKind::Modifiers.
- expand_item_multi_modifier(it, fld)
+ match multi_modifier {
+ None => expand_multi_modified(item, fld),
+ Some((attr, extension)) => match *extension {
+ MultiModifier(ref mac) => {
+ attr::mark_used(&attr);
+ fld.cx.bt_push(ExpnInfo {
+ call_site: attr.span,
+ callee: NameAndSpan {
+ format: MacroAttribute(intern(&attr.name())),
+ span: Some(attr.span),
+ // attributes can do whatever they like, for now
+ allow_internal_unstable: true,
+ }
+ });
+ let modified = mac.expand(fld.cx, attr.span, &attr.node.value, item);
+ fld.cx.bt_pop();
+ modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
+ }
+ _ => unreachable!(),
+ }
+ }
}
fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander)
}
}
+fn expand_trait_item(ti: ast::TraitItem, fld: &mut MacroExpander)
+ -> SmallVector<ast::TraitItem> {
+ match ti.node {
+ ast::TraitItemKind::Method(_, Some(_)) => {
+ SmallVector::one(ast::TraitItem {
+ id: ti.id,
+ ident: ti.ident,
+ attrs: ti.attrs,
+ node: match ti.node {
+ ast::TraitItemKind::Method(sig, Some(body)) => {
+ let (sig, body) = expand_and_rename_method(sig, body, fld);
+ ast::TraitItemKind::Method(sig, Some(body))
+ }
+ _ => unreachable!()
+ },
+ span: ti.span,
+ })
+ }
+ ast::TraitItemKind::Macro(mac) => {
+ expand_mac_invoc(mac, None, ti.attrs, ti.span, fld)
+ }
+ _ => fold::noop_fold_trait_item(ti, fld)
+ }
+}
+
/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
/// PatIdents in its arguments to perform renaming in the FnDecl and
/// the block, returning both the new FnDecl and the new Block.
at_crate_root: bool,
}
- impl<'a, 'b, 'v> Visitor<'v> for MacroLoadingVisitor<'a, 'b> {
- fn visit_mac(&mut self, _: &'v ast::Mac) {}
- fn visit_item(&mut self, item: &'v ast::Item) {
+ impl<'a, 'b> Visitor for MacroLoadingVisitor<'a, 'b> {
+ fn visit_mac(&mut self, _: &ast::Mac) {}
+ fn visit_item(&mut self, item: &ast::Item) {
if let ast::ItemKind::ExternCrate(..) = item.node {
// We need to error on `#[macro_use] extern crate` when it isn't at the
// crate root, because `$crate` won't work properly.
self.at_crate_root = at_crate_root;
}
}
- fn visit_block(&mut self, block: &'v ast::Block) {
+ fn visit_block(&mut self, block: &ast::Block) {
let at_crate_root = ::std::mem::replace(&mut self.at_crate_root, false);
visit::walk_block(self, block);
self.at_crate_root = at_crate_root;
fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
expr.and_then(|expr| match expr.node {
ast::ExprKind::Mac(mac) =>
- expand_mac_invoc(mac, None, expr.attrs.into_attr_vec(), expr.span, self),
+ expand_mac_invoc(mac, None, expr.attrs.into(), expr.span, self),
_ => Some(expand_expr(expr, self)),
})
}
result = expand_item(item, self);
self.pop_mod_path();
} else {
- let filename = if inner != codemap::DUMMY_SP {
+ let filename = if inner != syntax_pos::DUMMY_SP {
Some(self.cx.parse_sess.codemap().span_to_filename(inner))
} else { None };
let orig_filename = replace(&mut self.cx.filename, filename);
Spanned {
node: Mac_ {
path: self.fold_path(node.path),
- tts: self.fold_tts(&node.tts),
- ctxt: mtwt::apply_mark(self.mark, node.ctxt),
+ tts: self.fold_tts(node.tts),
},
span: self.new_span(span),
}
}
// apply a given mark to the given token trees. Used prior to expansion of a macro.
-fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec<TokenTree> {
+fn mark_tts(tts: Vec<TokenTree>, m: Mrk) -> Vec<TokenTree> {
noop_fold_tts(tts, &mut Marker{mark:m, expn_id: None})
}
use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig};
use ast;
use ast::Name;
- use codemap;
+ use syntax_pos;
use ext::base::{ExtCtxt, DummyMacroLoader};
use ext::mtwt;
use fold::Folder;
path_accumulator: Vec<ast::Path> ,
}
- impl<'v> Visitor<'v> for PathExprFinderContext {
+ impl Visitor for PathExprFinderContext {
fn visit_expr(&mut self, expr: &ast::Expr) {
if let ast::ExprKind::Path(None, ref p) = expr.node {
self.path_accumulator.push(p.clone());
ident_accumulator: Vec<ast::Ident>
}
- impl<'v> Visitor<'v> for IdentFinder {
- fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident){
+ impl Visitor for IdentFinder {
+ fn visit_ident(&mut self, _: syntax_pos::Span, id: ast::Ident){
self.ident_accumulator.push(id);
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use ast::{self, Arg, Arm, Block, Expr, Item, Pat, Stmt, TokenTree, Ty};
-use codemap::Span;
+use ast::{self, Arg, Arm, Block, Expr, Item, Pat, Stmt, Ty};
+use syntax_pos::Span;
use ext::base::ExtCtxt;
use ext::base;
use ext::build::AstBuilder;
use parse::token::*;
use parse::token;
use ptr::P;
+use tokenstream::{self, TokenTree};
/// Quasiquoting works via token trees.
///
use ext::base::ExtCtxt;
use parse::{self, token, classify};
use ptr::P;
- use std::rc::Rc;
- use ast::TokenTree;
+ use tokenstream::{self, TokenTree};
pub use parse::new_parser_from_tts;
- pub use codemap::{BytePos, Span, dummy_spanned, DUMMY_SP};
+ pub use syntax_pos::{BytePos, Span, DUMMY_SP};
+ pub use codemap::{dummy_spanned};
pub trait ToTokens {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree>;
if self.node.style == ast::AttrStyle::Inner {
r.push(TokenTree::Token(self.span, token::Not));
}
- r.push(TokenTree::Delimited(self.span, Rc::new(ast::Delimited {
+ r.push(TokenTree::Delimited(self.span, tokenstream::Delimited {
delim: token::Bracket,
open_span: self.span,
tts: self.node.value.to_tokens(cx),
close_span: self.span,
- })));
+ }));
r
}
}
impl ToTokens for () {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
- vec![TokenTree::Delimited(DUMMY_SP, Rc::new(ast::Delimited {
+ vec![TokenTree::Delimited(DUMMY_SP, tokenstream::Delimited {
delim: token::Paren,
open_span: DUMMY_SP,
tts: vec![],
close_span: DUMMY_SP,
- }))]
+ })]
}
}
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::Lit(P(self.clone())),
span: DUMMY_SP,
- attrs: None,
+ attrs: ast::ThinVec::new(),
}).to_tokens(cx)
}
}
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::Lit(P(dummy_spanned(lit))),
span: DUMMY_SP,
- attrs: None,
+ attrs: ast::ThinVec::new(),
});
if *self >= 0 {
return lit.to_tokens(cx);
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::Unary(ast::UnOp::Neg, lit),
span: DUMMY_SP,
- attrs: None,
+ attrs: ast::ThinVec::new(),
}).to_tokens(cx)
}
}
let (cx_expr, tts) = parse_arguments_to_quote(cx, tts);
let mut vector = mk_stmts_let(cx, sp);
vector.extend(statements_mk_tts(cx, &tts[..], true));
- let block = cx.expr_block(
- cx.block_all(sp,
- vector,
- Some(cx.expr_ident(sp, id_ext("tt")))));
+ vector.push(cx.stmt_expr(cx.expr_ident(sp, id_ext("tt"))));
+ let block = cx.expr_block(cx.block(sp, vector));
let expanded = expand_wrapper(cx, sp, cx_expr, block, &[&["syntax", "ext", "quote", "rt"]]);
base::MacEager::expr(expanded)
}
fn mk_tt_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> {
- let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext("TokenTree"), id_ext(name));
+ let idents = vec!(id_ext("syntax"), id_ext("tokenstream"), id_ext("TokenTree"), id_ext(name));
cx.expr_path(cx.path_global(sp, idents))
}
let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp));
let mut tts_stmts = vec![stmt_let_tt];
tts_stmts.extend(statements_mk_tts(cx, &seq.tts[..], matcher));
- let e_tts = cx.expr_block(cx.block(sp, tts_stmts,
- Some(cx.expr_ident(sp, id_ext("tt")))));
+ tts_stmts.push(cx.stmt_expr(cx.expr_ident(sp, id_ext("tt"))));
+ let e_tts = cx.expr_block(cx.block(sp, tts_stmts));
+
let e_separator = match seq.separator {
Some(ref sep) => cx.expr_some(sp, expr_mk_token(cx, sp, sep)),
None => cx.expr_none(sp),
};
let e_op = match seq.op {
- ast::KleeneOp::ZeroOrMore => "ZeroOrMore",
- ast::KleeneOp::OneOrMore => "OneOrMore",
+ tokenstream::KleeneOp::ZeroOrMore => "ZeroOrMore",
+ tokenstream::KleeneOp::OneOrMore => "OneOrMore",
};
let e_op_idents = vec![
id_ext("syntax"),
- id_ext("ast"),
+ id_ext("tokenstream"),
id_ext("KleeneOp"),
id_ext(e_op),
];
cx.field_imm(sp, id_ext("op"), e_op),
cx.field_imm(sp, id_ext("num_captures"),
cx.expr_usize(sp, seq.num_captures))];
- let seq_path = vec![id_ext("syntax"), id_ext("ast"), id_ext("SequenceRepetition")];
+ let seq_path = vec![id_ext("syntax"),
+ id_ext("tokenstream"),
+ id_ext("SequenceRepetition")];
let e_seq_struct = cx.expr_struct(sp, cx.path_global(sp, seq_path), fields);
- let e_rc_new = cx.expr_call_global(sp, vec![id_ext("std"),
- id_ext("rc"),
- id_ext("Rc"),
- id_ext("new")],
- vec![e_seq_struct]);
let e_tok = cx.expr_call(sp,
mk_tt_path(cx, sp, "Sequence"),
- vec!(e_sp, e_rc_new));
+ vec!(e_sp, e_seq_struct));
let e_push =
cx.expr_method_call(sp,
cx.expr_ident(sp, id_ext("tt")),
let mut vector = mk_stmts_let(cx, sp);
vector.extend(statements_mk_tts(cx, &tts[..], false));
- let block = cx.expr_block(
- cx.block_all(sp,
- vector,
- Some(cx.expr_ident(sp, id_ext("tt")))));
+ vector.push(cx.stmt_expr(cx.expr_ident(sp, id_ext("tt"))));
+ let block = cx.expr_block(cx.block(sp, vector));
(cx_expr, block)
}
let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr));
let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow);
- let stmts = imports.iter().map(|path| {
+ let mut stmts = imports.iter().map(|path| {
// make item: `use ...;`
let path = path.iter().map(|s| s.to_string()).collect();
cx.stmt_item(sp, cx.item_use_glob(sp, ast::Visibility::Inherited, ids_ext(path)))
- }).chain(Some(stmt_let_ext_cx)).collect();
+ }).chain(Some(stmt_let_ext_cx)).collect::<Vec<_>>();
+ stmts.push(cx.stmt_expr(expr));
- cx.expr_block(cx.block_all(sp, stmts, Some(expr)))
+ cx.expr_block(cx.block(sp, stmts))
}
fn expand_parse_call(cx: &ExtCtxt,
use ast::*;
use ast;
-use attr::{ThinAttributes, ThinAttributesExt};
-use codemap::{respan, Span, Spanned};
+use syntax_pos::Span;
+use codemap::{Spanned, respan};
use parse::token::{self, keywords};
use ptr::P;
+use tokenstream::*;
use util::small_vector::SmallVector;
use util::move_map::MoveMap;
-use std::rc::Rc;
-
pub trait Folder : Sized {
// Any additions to this trait should happen in form
// of a call to a public `noop_*` function that only calls
noop_fold_pat(p, self)
}
- fn fold_decl(&mut self, d: P<Decl>) -> SmallVector<P<Decl>> {
- noop_fold_decl(d, self)
- }
-
fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
e.map(|e| noop_fold_expr(e, self))
}
noop_fold_ty_params(tps, self)
}
- fn fold_tt(&mut self, tt: &TokenTree) -> TokenTree {
+ fn fold_tt(&mut self, tt: TokenTree) -> TokenTree {
noop_fold_tt(tt, self)
}
- fn fold_tts(&mut self, tts: &[TokenTree]) -> Vec<TokenTree> {
+ fn fold_tts(&mut self, tts: Vec<TokenTree>) -> Vec<TokenTree> {
noop_fold_tts(tts, self)
}
attrs.move_flat_map(|x| fld.fold_attribute(x))
}
-pub fn fold_thin_attrs<T: Folder>(attrs: ThinAttributes, fld: &mut T) -> ThinAttributes {
- attrs.map_thin_attrs(|v| fold_attrs(v, fld))
+pub fn fold_thin_attrs<T: Folder>(attrs: ThinVec<Attribute>, fld: &mut T) -> ThinVec<Attribute> {
+ fold_attrs(attrs.into(), fld).into()
}
pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm {
}
}
-pub fn noop_fold_decl<T: Folder>(d: P<Decl>, fld: &mut T) -> SmallVector<P<Decl>> {
- d.and_then(|Spanned {node, span}| match node {
- DeclKind::Local(l) => SmallVector::one(P(Spanned {
- node: DeclKind::Local(fld.fold_local(l)),
- span: fld.new_span(span)
- })),
- DeclKind::Item(it) => fld.fold_item(it).into_iter().map(|i| P(Spanned {
- node: DeclKind::Item(i),
- span: fld.new_span(span)
- })).collect()
- })
-}
-
pub fn noop_fold_ty_binding<T: Folder>(b: TypeBinding, fld: &mut T) -> TypeBinding {
TypeBinding {
id: fld.new_id(b.id),
pat: fld.fold_pat(pat),
init: init.map(|e| fld.fold_expr(e)),
span: fld.new_span(span),
- attrs: attrs.map_thin_attrs(|v| fold_attrs(v, fld)),
+ attrs: fold_attrs(attrs.into(), fld).into(),
})
}
Spanned {
node: Mac_ {
path: fld.fold_path(node.path),
- tts: fld.fold_tts(&node.tts),
- ctxt: node.ctxt,
+ tts: fld.fold_tts(node.tts),
},
span: fld.new_span(span)
}
}
}
-pub fn noop_fold_tt<T: Folder>(tt: &TokenTree, fld: &mut T) -> TokenTree {
- match *tt {
+pub fn noop_fold_tt<T: Folder>(tt: TokenTree, fld: &mut T) -> TokenTree {
+ match tt {
TokenTree::Token(span, ref tok) =>
TokenTree::Token(span, fld.fold_token(tok.clone())),
- TokenTree::Delimited(span, ref delimed) => {
- TokenTree::Delimited(span, Rc::new(
- Delimited {
- delim: delimed.delim,
- open_span: delimed.open_span,
- tts: fld.fold_tts(&delimed.tts),
- close_span: delimed.close_span,
- }
- ))
- },
- TokenTree::Sequence(span, ref seq) =>
- TokenTree::Sequence(span,
- Rc::new(SequenceRepetition {
- tts: fld.fold_tts(&seq.tts),
- separator: seq.separator.clone().map(|tok| fld.fold_token(tok)),
- ..**seq
- })),
+ TokenTree::Delimited(span, delimed) => TokenTree::Delimited(span, Delimited {
+ delim: delimed.delim,
+ open_span: delimed.open_span,
+ tts: fld.fold_tts(delimed.tts),
+ close_span: delimed.close_span,
+ }),
+ TokenTree::Sequence(span, seq) => TokenTree::Sequence(span, SequenceRepetition {
+ tts: fld.fold_tts(seq.tts),
+ separator: seq.separator.clone().map(|tok| fld.fold_token(tok)),
+ ..seq
+ }),
}
}
-pub fn noop_fold_tts<T: Folder>(tts: &[TokenTree], fld: &mut T) -> Vec<TokenTree> {
- // FIXME: Does this have to take a tts slice?
- // Could use move_map otherwise...
- tts.iter().map(|tt| fld.fold_tt(tt)).collect()
+pub fn noop_fold_tts<T: Folder>(tts: Vec<TokenTree>, fld: &mut T) -> Vec<TokenTree> {
+ tts.move_map(|tt| fld.fold_tt(tt))
}
// apply ident folder if it's an ident, apply other folds to interpolated nodes
token::NtIdent(Box::new(Spanned::<Ident>{node: fld.fold_ident(id.node), ..*id})),
token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)),
token::NtPath(path) => token::NtPath(Box::new(fld.fold_path(*path))),
- token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&tt))),
+ token::NtTT(tt) => token::NtTT(tt.map(|tt| fld.fold_tt(tt))),
token::NtArm(arm) => token::NtArm(fld.fold_arm(arm)),
token::NtImplItem(arm) =>
token::NtImplItem(arm.map(|arm| fld.fold_impl_item(arm)
}
pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
- b.map(|Block {id, stmts, expr, rules, span}| Block {
+ b.map(|Block {id, stmts, rules, span}| Block {
id: folder.new_id(id),
stmts: stmts.move_flat_map(|s| folder.fold_stmt(s).into_iter()),
- expr: expr.and_then(|x| folder.fold_opt_expr(x)),
rules: rules,
span: folder.new_span(span),
})
TraitItemKind::Type(folder.fold_bounds(bounds),
default.map(|x| folder.fold_ty(x)))
}
+ ast::TraitItemKind::Macro(mac) => {
+ TraitItemKind::Macro(folder.fold_mac(mac))
+ }
},
span: folder.new_span(i.span)
})
PatKind::TupleStruct(folder.fold_path(pth),
pats.move_map(|x| folder.fold_pat(x)), ddpos)
}
- PatKind::Path(pth) => {
- PatKind::Path(folder.fold_path(pth))
- }
- PatKind::QPath(qself, pth) => {
- let qself = QSelf {ty: folder.fold_ty(qself.ty), .. qself};
- PatKind::QPath(qself, folder.fold_path(pth))
+ PatKind::Path(opt_qself, pth) => {
+ let opt_qself = opt_qself.map(|qself| {
+ QSelf { ty: folder.fold_ty(qself.ty), position: qself.position }
+ });
+ PatKind::Path(opt_qself, folder.fold_path(pth))
}
PatKind::Struct(pth, fields, etc) => {
let pth = folder.fold_path(pth);
respan(folder.new_span(label.span),
folder.fold_ident(label.node)))
),
- ExprKind::Again(opt_ident) => ExprKind::Again(opt_ident.map(|label|
+ ExprKind::Continue(opt_ident) => ExprKind::Continue(opt_ident.map(|label|
respan(folder.new_span(label.span),
folder.fold_ident(label.node)))
),
ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)),
},
span: folder.new_span(span),
- attrs: attrs.map_thin_attrs(|v| fold_attrs(v, folder)),
+ attrs: fold_attrs(attrs.into(), folder).into(),
}
}
es.move_flat_map(|e| folder.fold_opt_expr(e))
}
-pub fn noop_fold_stmt<T: Folder>(Spanned {node, span}: Stmt, folder: &mut T)
+pub fn noop_fold_stmt<T: Folder>(Stmt {node, span, id}: Stmt, folder: &mut T)
-> SmallVector<Stmt> {
+ let id = folder.new_id(id);
let span = folder.new_span(span);
+
match node {
- StmtKind::Decl(d, id) => {
- let id = folder.new_id(id);
- folder.fold_decl(d).into_iter().map(|d| Spanned {
- node: StmtKind::Decl(d, id),
- span: span
- }).collect()
- }
- StmtKind::Expr(e, id) => {
- let id = folder.new_id(id);
- if let Some(e) = folder.fold_opt_expr(e) {
- SmallVector::one(Spanned {
- node: StmtKind::Expr(e, id),
- span: span
+ StmtKind::Local(local) => SmallVector::one(Stmt {
+ id: id,
+ node: StmtKind::Local(folder.fold_local(local)),
+ span: span,
+ }),
+ StmtKind::Item(item) => folder.fold_item(item).into_iter().map(|item| Stmt {
+ id: id,
+ node: StmtKind::Item(item),
+ span: span,
+ }).collect(),
+ StmtKind::Expr(expr) => {
+ if let Some(expr) = folder.fold_opt_expr(expr) {
+ SmallVector::one(Stmt {
+ id: id,
+ node: StmtKind::Expr(expr),
+ span: span,
})
} else {
SmallVector::zero()
}
}
- StmtKind::Semi(e, id) => {
- let id = folder.new_id(id);
- if let Some(e) = folder.fold_opt_expr(e) {
- SmallVector::one(Spanned {
- node: StmtKind::Semi(e, id),
- span: span
+ StmtKind::Semi(expr) => {
+ if let Some(expr) = folder.fold_opt_expr(expr) {
+ SmallVector::one(Stmt {
+ id: id,
+ node: StmtKind::Semi(expr),
+ span: span,
})
} else {
SmallVector::zero()
}
}
- StmtKind::Mac(mac, semi, attrs) => SmallVector::one(Spanned {
- node: StmtKind::Mac(mac.map(|m| folder.fold_mac(m)),
- semi,
- attrs.map_thin_attrs(|v| fold_attrs(v, folder))),
- span: span
+ StmtKind::Mac(mac) => SmallVector::one(Stmt {
+ id: id,
+ node: StmtKind::Mac(mac.map(|(mac, semi, attrs)| {
+ (folder.fold_mac(mac), semi, fold_attrs(attrs.into(), folder).into())
+ })),
+ span: span,
})
}
}
//! The main parser interface
use ast;
-use codemap::{self, Span, CodeMap, FileMap};
+use codemap::CodeMap;
+use syntax_pos::{self, Span, FileMap};
use errors::{Handler, ColorConfig, DiagnosticBuilder};
use parse::parser::Parser;
use parse::token::InternedString;
use ptr::P;
use str::char_at;
+use tokenstream;
use std::cell::RefCell;
use std::iter;
source: String,
cfg: ast::CrateConfig,
sess: &'a ParseSess)
- -> PResult<'a, Vec<ast::TokenTree>> {
+ -> PResult<'a, Vec<tokenstream::TokenTree>> {
let mut p = new_parser_from_source_str(
sess,
cfg,
let end_pos = filemap.end_pos;
let mut parser = tts_to_parser(sess, filemap_to_tts(sess, filemap), cfg);
- if parser.token == token::Eof && parser.span == codemap::DUMMY_SP {
- parser.span = codemap::mk_sp(end_pos, end_pos);
+ if parser.token == token::Eof && parser.span == syntax_pos::DUMMY_SP {
+ parser.span = syntax_pos::mk_sp(end_pos, end_pos);
}
parser
// compiler expands into it
pub fn new_parser_from_tts<'a>(sess: &'a ParseSess,
cfg: ast::CrateConfig,
- tts: Vec<ast::TokenTree>) -> Parser<'a> {
+ tts: Vec<tokenstream::TokenTree>) -> Parser<'a> {
tts_to_parser(sess, tts, cfg)
}
/// Given a filemap, produce a sequence of token-trees
pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
- -> Vec<ast::TokenTree> {
+ -> Vec<tokenstream::TokenTree> {
// it appears to me that the cfg doesn't matter here... indeed,
// parsing tt's probably shouldn't require a parser at all.
let cfg = Vec::new();
/// Given tts and cfg, produce a parser
pub fn tts_to_parser<'a>(sess: &'a ParseSess,
- tts: Vec<ast::TokenTree>,
+ tts: Vec<tokenstream::TokenTree>,
cfg: ast::CrateConfig) -> Parser<'a> {
let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, None, tts);
let mut p = Parser::new(sess, cfg, Box::new(trdr));
#[cfg(test)]
mod tests {
use super::*;
- use std::rc::Rc;
- use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
- use ast::{self, TokenTree, PatKind};
+ use syntax_pos::{Span, BytePos, Pos, NO_EXPANSION};
+ use codemap::Spanned;
+ use ast::{self, PatKind};
use abi::Abi;
use attr::{first_attr_value_str_by_name, AttrMetaMethods};
use parse;
use parse::token::{str_to_ident};
use print::pprust::item_to_string;
use ptr::P;
+ use tokenstream::{self, TokenTree};
use util::parser_testing::{string_to_tts, string_to_parser};
use util::parser_testing::{string_to_expr, string_to_item, string_to_stmt};
+ use util::ThinVec;
- // produce a codemap::span
+ // produce a syntax_pos::span
fn sp(a: u32, b: u32) -> Span {
Span {lo: BytePos(a), hi: BytePos(b), expn_id: NO_EXPANSION}
}
),
}),
span: sp(0, 1),
- attrs: None,
+ attrs: ThinVec::new(),
}))
}
)
}),
span: sp(0, 6),
- attrs: None,
+ attrs: ThinVec::new(),
}))
}
#[test]
fn string_to_tts_macro () {
let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_string());
- let tts: &[ast::TokenTree] = &tts[..];
+ let tts: &[tokenstream::TokenTree] = &tts[..];
match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) {
(
)
if first_delimed.delim == token::Paren
&& ident.name.as_str() == "a" => {},
- _ => panic!("value 3: {:?}", **first_delimed),
+ _ => panic!("value 3: {:?}", *first_delimed),
}
let tts = &second_delimed.tts[..];
match (tts.len(), tts.get(0), tts.get(1)) {
)
if second_delimed.delim == token::Paren
&& ident.name.as_str() == "a" => {},
- _ => panic!("value 4: {:?}", **second_delimed),
+ _ => panic!("value 4: {:?}", *second_delimed),
}
},
- _ => panic!("value 2: {:?}", **macro_delimed),
+ _ => panic!("value 2: {:?}", *macro_delimed),
}
},
_ => panic!("value: {:?}",tts),
TokenTree::Token(sp(3, 4), token::Ident(str_to_ident("a"))),
TokenTree::Delimited(
sp(5, 14),
- Rc::new(ast::Delimited {
+ tokenstream::Delimited {
delim: token::DelimToken::Paren,
open_span: sp(5, 6),
tts: vec![
TokenTree::Token(sp(10, 13), token::Ident(str_to_ident("i32"))),
],
close_span: sp(13, 14),
- })),
+ }),
TokenTree::Delimited(
sp(15, 21),
- Rc::new(ast::Delimited {
+ tokenstream::Delimited {
delim: token::DelimToken::Brace,
open_span: sp(15, 16),
tts: vec![
TokenTree::Token(sp(18, 19), token::Semi),
],
close_span: sp(20, 21),
- }))
+ })
];
assert_eq!(tts, expected);
),
}),
span:sp(7,8),
- attrs: None,
+ attrs: ThinVec::new(),
}))),
span:sp(0,8),
- attrs: None,
+ attrs: ThinVec::new(),
}))
}
#[test] fn parse_stmt_1 () {
assert!(string_to_stmt("b;".to_string()) ==
- Some(Spanned{
+ Some(ast::Stmt {
node: ast::StmtKind::Expr(P(ast::Expr {
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::Path(None, ast::Path {
),
}),
span: sp(0,1),
- attrs: None}),
- ast::DUMMY_NODE_ID),
+ attrs: ThinVec::new()})),
+ id: ast::DUMMY_NODE_ID,
span: sp(0,1)}))
}
}
},
P(ast::Block {
- stmts: vec!(Spanned{
+ stmts: vec!(ast::Stmt {
node: ast::StmtKind::Semi(P(ast::Expr{
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::Path(None,
),
}),
span: sp(17,18),
- attrs: None,}),
- ast::DUMMY_NODE_ID),
+ attrs: ThinVec::new()})),
+ id: ast::DUMMY_NODE_ID,
span: sp(17,19)}),
- expr: None,
id: ast::DUMMY_NODE_ID,
rules: ast::BlockCheckMode::Default, // no idea
span: sp(15,21),
struct PatIdentVisitor {
spans: Vec<Span>
}
- impl<'v> ::visit::Visitor<'v> for PatIdentVisitor {
- fn visit_pat(&mut self, p: &'v ast::Pat) {
+ impl ::visit::Visitor for PatIdentVisitor {
+ fn visit_pat(&mut self, p: &ast::Pat) {
match p.node {
PatKind::Ident(_ , ref spannedident, _) => {
self.spans.push(spannedident.span.clone());
use ast::Block;
use ast::{BlockCheckMode, CaptureBy};
use ast::{Constness, Crate, CrateConfig};
-use ast::{Decl, DeclKind, Defaultness};
-use ast::{EMPTY_CTXT, EnumDef};
+use ast::Defaultness;
+use ast::EnumDef;
use ast::{Expr, ExprKind, RangeLimits};
use ast::{Field, FnDecl};
use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
use ast::{VariantData, StructField};
use ast::StrStyle;
use ast::SelfKind;
-use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
+use ast::{TraitItem, TraitRef};
use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds};
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
use ast::{Visibility, WhereClause};
-use attr::{ThinAttributes, ThinAttributesExt, AttributesExt};
use ast::{BinOpKind, UnOp};
use ast;
-use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
+use codemap::{self, CodeMap, Spanned, spanned};
+use syntax_pos::{self, Span, BytePos, mk_sp};
use errors::{self, DiagnosticBuilder};
use ext::tt::macro_parser;
use parse;
use print::pprust;
use ptr::P;
use parse::PResult;
+use tokenstream::{self, Delimited, SequenceRepetition, TokenTree};
+use util::ThinVec;
use std::collections::HashSet;
use std::mem;
_ => unreachable!()
};
let span = $p.span;
- Some($p.mk_expr(span.lo, span.hi, ExprKind::Path(None, pt), None))
+ Some($p.mk_expr(span.lo, span.hi, ExprKind::Path(None, pt), ThinVec::new()))
}
token::Interpolated(token::NtBlock(_)) => {
// FIXME: The following avoids an issue with lexical borrowck scopes,
_ => unreachable!()
};
let span = $p.span;
- Some($p.mk_expr(span.lo, span.hi, ExprKind::Block(b), None))
+ Some($p.mk_expr(span.lo, span.hi, ExprKind::Block(b), ThinVec::new()))
}
_ => None
};
pub enum LhsExpr {
NotYetParsed,
- AttributesParsed(ThinAttributes),
+ AttributesParsed(ThinVec<Attribute>),
AlreadyParsed(P<Expr>),
}
-impl From<Option<ThinAttributes>> for LhsExpr {
- fn from(o: Option<ThinAttributes>) -> Self {
+impl From<Option<ThinVec<Attribute>>> for LhsExpr {
+ fn from(o: Option<ThinVec<Attribute>>) -> Self {
if let Some(attrs) = o {
LhsExpr::AttributesParsed(attrs)
} else {
{
let tok0 = rdr.real_token();
let span = tok0.sp;
- let filename = if span != codemap::DUMMY_SP {
+ let filename = if span != syntax_pos::DUMMY_SP {
Some(sess.codemap().span_to_filename(span))
} else { None };
let placeholder = TokenAndSpan {
}
/// Parse the items in a trait declaration
- pub fn parse_trait_items(&mut self) -> PResult<'a, Vec<TraitItem>> {
- self.parse_unspanned_seq(
- &token::OpenDelim(token::Brace),
- &token::CloseDelim(token::Brace),
- SeqSep::none(),
- |p| -> PResult<'a, TraitItem> {
- maybe_whole!(no_clone_from_p p, NtTraitItem);
- let mut attrs = p.parse_outer_attributes()?;
- let lo = p.span.lo;
-
- let (name, node) = if p.eat_keyword(keywords::Type) {
- let TyParam {ident, bounds, default, ..} = p.parse_ty_param()?;
- p.expect(&token::Semi)?;
- (ident, TraitItemKind::Type(bounds, default))
- } else if p.is_const_item() {
- p.expect_keyword(keywords::Const)?;
- let ident = p.parse_ident()?;
- p.expect(&token::Colon)?;
- let ty = p.parse_ty_sum()?;
- let default = if p.check(&token::Eq) {
- p.bump();
- let expr = p.parse_expr()?;
- p.commit_expr_expecting(&expr, token::Semi)?;
- Some(expr)
- } else {
- p.expect(&token::Semi)?;
- None
- };
- (ident, TraitItemKind::Const(ty, default))
+ pub fn parse_trait_item(&mut self) -> PResult<'a, TraitItem> {
+ maybe_whole!(no_clone_from_p self, NtTraitItem);
+ let mut attrs = self.parse_outer_attributes()?;
+ let lo = self.span.lo;
+
+ let (name, node) = if self.eat_keyword(keywords::Type) {
+ let TyParam {ident, bounds, default, ..} = self.parse_ty_param()?;
+ self.expect(&token::Semi)?;
+ (ident, TraitItemKind::Type(bounds, default))
+ } else if self.is_const_item() {
+ self.expect_keyword(keywords::Const)?;
+ let ident = self.parse_ident()?;
+ self.expect(&token::Colon)?;
+ let ty = self.parse_ty_sum()?;
+ let default = if self.check(&token::Eq) {
+ self.bump();
+ let expr = self.parse_expr()?;
+ self.commit_expr_expecting(&expr, token::Semi)?;
+ Some(expr)
+ } else {
+ self.expect(&token::Semi)?;
+ None
+ };
+ (ident, TraitItemKind::Const(ty, default))
+ } else if !self.token.is_any_keyword()
+ && self.look_ahead(1, |t| *t == token::Not)
+ && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren))
+ || self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))) {
+ // trait item macro.
+ // code copied from parse_macro_use_or_failure... abstraction!
+ let lo = self.span.lo;
+ let pth = self.parse_ident_into_path()?;
+ self.expect(&token::Not)?;
+
+ // eat a matched-delimiter token tree:
+ let delim = self.expect_open_delim()?;
+ let tts = self.parse_seq_to_end(&token::CloseDelim(delim),
+ SeqSep::none(),
+ |pp| pp.parse_token_tree())?;
+ let m_ = Mac_ { path: pth, tts: tts };
+ let m: ast::Mac = codemap::Spanned { node: m_,
+ span: mk_sp(lo,
+ self.last_span.hi) };
+ if delim != token::Brace {
+ self.expect(&token::Semi)?
+ }
+ (keywords::Invalid.ident(), ast::TraitItemKind::Macro(m))
} else {
- let (constness, unsafety, abi) = match p.parse_fn_front_matter() {
+ let (constness, unsafety, abi) = match self.parse_fn_front_matter() {
Ok(cua) => cua,
Err(e) => {
loop {
- match p.token {
+ match self.token {
token::Eof => break,
-
token::CloseDelim(token::Brace) |
token::Semi => {
- p.bump();
+ self.bump();
break;
}
-
token::OpenDelim(token::Brace) => {
- p.parse_token_tree()?;
+ self.parse_token_tree()?;
break;
}
-
- _ => p.bump()
+ _ => self.bump()
}
}
}
};
- let ident = p.parse_ident()?;
- let mut generics = p.parse_generics()?;
+ let ident = self.parse_ident()?;
+ let mut generics = self.parse_generics()?;
- let d = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
+ let d = self.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
// This is somewhat dubious; We don't want to allow
// argument names to be left off if there is a
// definition...
p.parse_arg_general(false)
})?;
- generics.where_clause = p.parse_where_clause()?;
+ generics.where_clause = self.parse_where_clause()?;
let sig = ast::MethodSig {
unsafety: unsafety,
constness: constness,
abi: abi,
};
- let body = match p.token {
- token::Semi => {
- p.bump();
- debug!("parse_trait_methods(): parsing required method");
- None
- }
- token::OpenDelim(token::Brace) => {
- debug!("parse_trait_methods(): parsing provided method");
- let (inner_attrs, body) =
- p.parse_inner_attrs_and_block()?;
- attrs.extend(inner_attrs.iter().cloned());
- Some(body)
- }
+ let body = match self.token {
+ token::Semi => {
+ self.bump();
+ debug!("parse_trait_methods(): parsing required method");
+ None
+ }
+ token::OpenDelim(token::Brace) => {
+ debug!("parse_trait_methods(): parsing provided method");
+ let (inner_attrs, body) =
+ self.parse_inner_attrs_and_block()?;
+ attrs.extend(inner_attrs.iter().cloned());
+ Some(body)
+ }
- _ => {
- let token_str = p.this_token_to_string();
- return Err(p.fatal(&format!("expected `;` or `{{`, found `{}`",
- token_str)[..]))
- }
+ _ => {
+ let token_str = self.this_token_to_string();
+ return Err(self.fatal(&format!("expected `;` or `{{`, found `{}`",
+ token_str)[..]))
+ }
};
(ident, ast::TraitItemKind::Method(sig, body))
};
+ Ok(TraitItem {
+ id: ast::DUMMY_NODE_ID,
+ ident: name,
+ attrs: attrs,
+ node: node,
+ span: mk_sp(lo, self.last_span.hi),
+ })
+ }
- Ok(TraitItem {
- id: ast::DUMMY_NODE_ID,
- ident: name,
- attrs: attrs,
- node: node,
- span: mk_sp(lo, p.last_span.hi),
+
+ /// Parse the items in a trait declaration
+ pub fn parse_trait_items(&mut self) -> PResult<'a, Vec<TraitItem>> {
+ self.parse_unspanned_seq(
+ &token::OpenDelim(token::Brace),
+ &token::CloseDelim(token::Brace),
+ SeqSep::none(),
+ |p| -> PResult<'a, TraitItem> {
+ p.parse_trait_item()
})
- })
}
/// Parse a possibly mutable type
SeqSep::none(),
|p| p.parse_token_tree())?;
let hi = self.span.hi;
- TyKind::Mac(spanned(lo, hi, Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT }))
+ TyKind::Mac(spanned(lo, hi, Mac_ { path: path, tts: tts }))
} else {
// NAMED TYPE
TyKind::Path(None, path)
let lo = self.span.lo;
let literal = P(self.parse_lit()?);
let hi = self.last_span.hi;
- let expr = self.mk_expr(lo, hi, ExprKind::Lit(literal), None);
+ let expr = self.mk_expr(lo, hi, ExprKind::Lit(literal), ThinVec::new());
if minus_present {
let minus_hi = self.last_span.hi;
let unary = self.mk_unary(UnOp::Neg, expr);
- Ok(self.mk_expr(minus_lo, minus_hi, unary, None))
+ Ok(self.mk_expr(minus_lo, minus_hi, unary, ThinVec::new()))
} else {
Ok(expr)
}
})
}
- pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos,
- node: ExprKind, attrs: ThinAttributes) -> P<Expr> {
+ pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: ExprKind, attrs: ThinVec<Attribute>)
+ -> P<Expr> {
P(Expr {
id: ast::DUMMY_NODE_ID,
node: node,
span: mk_sp(lo, hi),
- attrs: attrs,
+ attrs: attrs.into(),
})
}
}
pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos,
- m: Mac_, attrs: ThinAttributes) -> P<Expr> {
+ m: Mac_, attrs: ThinVec<Attribute>) -> P<Expr> {
P(Expr {
id: ast::DUMMY_NODE_ID,
node: ExprKind::Mac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}),
})
}
- pub fn mk_lit_u32(&mut self, i: u32, attrs: ThinAttributes) -> P<Expr> {
+ pub fn mk_lit_u32(&mut self, i: u32, attrs: ThinVec<Attribute>) -> P<Expr> {
let span = &self.span;
let lv_lit = P(codemap::Spanned {
node: LitKind::Int(i as u64, ast::LitIntType::Unsigned(UintTy::U32)),
//
// Therefore, prevent sub-parser from parsing
// attributes by giving them a empty "already parsed" list.
- let mut attrs = None;
+ let mut attrs = ThinVec::new();
let lo = self.span.lo;
let mut hi = self.span.hi;
token::OpenDelim(token::Paren) => {
self.bump();
- let attrs = self.parse_inner_attributes()?
- .into_thin_attrs()
- .prepend(attrs);
+ attrs.extend(self.parse_inner_attributes()?);
// (e) is parenthesized e
// (e,) is a tuple with only one field, e
token::OpenDelim(token::Bracket) => {
self.bump();
- let inner_attrs = self.parse_inner_attributes()?
- .into_thin_attrs();
- attrs.update(|attrs| attrs.append(inner_attrs));
+ attrs.extend(self.parse_inner_attributes()?);
if self.check(&token::CloseDelim(token::Bracket)) {
// Empty vector.
}
if self.eat_keyword(keywords::Continue) {
let ex = if self.token.is_lifetime() {
- let ex = ExprKind::Again(Some(Spanned{
+ let ex = ExprKind::Continue(Some(Spanned{
node: self.get_lifetime(),
span: self.span
}));
self.bump();
ex
} else {
- ExprKind::Again(None)
+ ExprKind::Continue(None)
};
let hi = self.last_span.hi;
return Ok(self.mk_expr(lo, hi, ex, attrs));
return Ok(self.mk_mac_expr(lo,
hi,
- Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT },
+ Mac_ { path: pth, tts: tts },
attrs));
}
if self.check(&token::OpenDelim(token::Brace)) {
let mut fields = Vec::new();
let mut base = None;
- let attrs = attrs.append(
- self.parse_inner_attributes()?
- .into_thin_attrs());
+ attrs.extend(self.parse_inner_attributes()?);
while self.token != token::CloseDelim(token::Brace) {
if self.eat(&token::DotDot) {
}
fn parse_or_use_outer_attributes(&mut self,
- already_parsed_attrs: Option<ThinAttributes>)
- -> PResult<'a, ThinAttributes> {
+ already_parsed_attrs: Option<ThinVec<Attribute>>)
+ -> PResult<'a, ThinVec<Attribute>> {
if let Some(attrs) = already_parsed_attrs {
Ok(attrs)
} else {
- self.parse_outer_attributes().map(|a| a.into_thin_attrs())
+ self.parse_outer_attributes().map(|a| a.into())
}
}
/// Parse a block or unsafe block
pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode,
- attrs: ThinAttributes)
+ outer_attrs: ThinVec<Attribute>)
-> PResult<'a, P<Expr>> {
- let outer_attrs = attrs;
self.expect(&token::OpenDelim(token::Brace))?;
- let inner_attrs = self.parse_inner_attributes()?.into_thin_attrs();
- let attrs = outer_attrs.append(inner_attrs);
+ let mut attrs = outer_attrs;
+ attrs.extend(self.parse_inner_attributes()?);
let blk = self.parse_block_tail(lo, blk_mode)?;
return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprKind::Block(blk), attrs));
/// parse a.b or a(13) or a[4] or just a
pub fn parse_dot_or_call_expr(&mut self,
- already_parsed_attrs: Option<ThinAttributes>)
+ already_parsed_attrs: Option<ThinVec<Attribute>>)
-> PResult<'a, P<Expr>> {
let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
pub fn parse_dot_or_call_expr_with(&mut self,
e0: P<Expr>,
lo: BytePos,
- attrs: ThinAttributes)
+ mut attrs: ThinVec<Attribute>)
-> PResult<'a, P<Expr>> {
// Stitch the list of outer attributes onto the return value.
// A little bit ugly, but the best way given the current code
self.parse_dot_or_call_expr_with_(e0, lo)
.map(|expr|
expr.map(|mut expr| {
- expr.attrs.update(|a| a.prepend(attrs));
+ attrs.extend::<Vec<_>>(expr.attrs.into());
+ expr.attrs = attrs;
match expr.node {
ExprKind::If(..) | ExprKind::IfLet(..) => {
- if !expr.attrs.as_attr_slice().is_empty() {
+ if !expr.attrs.is_empty() {
// Just point to the first attribute in there...
- let span = expr.attrs.as_attr_slice()[0].span;
+ let span = expr.attrs[0].span;
self.span_err(span,
"attributes are not yet allowed on `if` \
es.insert(0, self_value);
let id = spanned(ident_span.lo, ident_span.hi, ident);
let nd = self.mk_method_call(id, tys, es);
- self.mk_expr(lo, hi, nd, None)
+ self.mk_expr(lo, hi, nd, ThinVec::new())
}
// Field access.
_ => {
let id = spanned(ident_span.lo, ident_span.hi, ident);
let field = self.mk_field(self_value, id);
- self.mk_expr(lo, ident_span.hi, field, None)
+ self.mk_expr(lo, ident_span.hi, field, ThinVec::new())
}
})
}
// expr?
while self.eat(&token::Question) {
let hi = self.last_span.hi;
- e = self.mk_expr(lo, hi, ExprKind::Try(e), None);
+ e = self.mk_expr(lo, hi, ExprKind::Try(e), ThinVec::new());
}
// expr.f
Some(n) => {
let id = spanned(dot, hi, n);
let field = self.mk_tup_field(e, id);
- e = self.mk_expr(lo, hi, field, None);
+ e = self.mk_expr(lo, hi, field, ThinVec::new());
}
None => {
let last_span = self.last_span;
hi = self.last_span.hi;
let nd = self.mk_call(e, es);
- e = self.mk_expr(lo, hi, nd, None);
+ e = self.mk_expr(lo, hi, nd, ThinVec::new());
}
// expr[...]
hi = self.span.hi;
self.commit_expr_expecting(&ix, token::CloseDelim(token::Bracket))?;
let index = self.mk_index(e, ix);
- e = self.mk_expr(lo, hi, index, None)
+ e = self.mk_expr(lo, hi, index, ThinVec::new())
}
_ => return Ok(e)
}
)?;
let (sep, repeat) = self.parse_sep_and_kleene_op()?;
let name_num = macro_parser::count_names(&seq);
- return Ok(TokenTree::Sequence(mk_sp(sp.lo, seq_span.hi),
- Rc::new(SequenceRepetition {
- tts: seq,
- separator: sep,
- op: repeat,
- num_captures: name_num
- })));
+ return Ok(TokenTree::Sequence(mk_sp(sp.lo, seq_span.hi), SequenceRepetition {
+ tts: seq,
+ separator: sep,
+ op: repeat,
+ num_captures: name_num
+ }));
} else if self.token.is_keyword(keywords::Crate) {
self.bump();
return Ok(TokenTree::Token(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar)));
/// Parse an optional separator followed by a Kleene-style
/// repetition token (+ or *).
pub fn parse_sep_and_kleene_op(&mut self)
- -> PResult<'a, (Option<token::Token>, ast::KleeneOp)> {
- fn parse_kleene_op<'a>(parser: &mut Parser<'a>) -> PResult<'a, Option<ast::KleeneOp>> {
+ -> PResult<'a, (Option<token::Token>, tokenstream::KleeneOp)> {
+ fn parse_kleene_op<'a>(parser: &mut Parser<'a>) ->
+ PResult<'a, Option<tokenstream::KleeneOp>> {
match parser.token {
token::BinOp(token::Star) => {
parser.bump();
- Ok(Some(ast::KleeneOp::ZeroOrMore))
+ Ok(Some(tokenstream::KleeneOp::ZeroOrMore))
},
token::BinOp(token::Plus) => {
parser.bump();
- Ok(Some(ast::KleeneOp::OneOrMore))
+ Ok(Some(tokenstream::KleeneOp::OneOrMore))
},
_ => Ok(None)
}
_ => {}
}
- Ok(TokenTree::Delimited(span, Rc::new(Delimited {
+ Ok(TokenTree::Delimited(span, Delimited {
delim: delim,
open_span: open_span,
tts: tts,
close_span: close_span,
- })))
+ }))
},
_ => {
// invariants: the current token is not a left-delimiter,
/// Parse a prefix-unary-operator expr
pub fn parse_prefix_expr(&mut self,
- already_parsed_attrs: Option<ThinAttributes>)
+ already_parsed_attrs: Option<ThinVec<Attribute>>)
-> PResult<'a, P<Expr>> {
let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
let lo = self.span.lo;
let blk = self.parse_block()?;
let span = blk.span;
hi = span.hi;
- let blk_expr = self.mk_expr(span.lo, span.hi, ExprKind::Block(blk),
- None);
+ let blk_expr = self.mk_expr(span.lo, hi, ExprKind::Block(blk), ThinVec::new());
ExprKind::InPlace(place, blk_expr)
}
token::Ident(..) if self.token.is_keyword(keywords::Box) => {
/// This parses an expression accounting for associativity and precedence of the operators in
/// the expression.
pub fn parse_assoc_expr(&mut self,
- already_parsed_attrs: Option<ThinAttributes>)
+ already_parsed_attrs: Option<ThinVec<Attribute>>)
-> PResult<'a, P<Expr>> {
self.parse_assoc_expr_with(0, already_parsed_attrs.into())
}
// Special cases:
if op == AssocOp::As {
let rhs = self.parse_ty()?;
- lhs = self.mk_expr(lhs_span.lo, rhs.span.hi,
- ExprKind::Cast(lhs, rhs), None);
+ let (lo, hi) = (lhs_span.lo, rhs.span.hi);
+ lhs = self.mk_expr(lo, hi, ExprKind::Cast(lhs, rhs), ThinVec::new());
continue
} else if op == AssocOp::Colon {
let rhs = self.parse_ty()?;
- lhs = self.mk_expr(lhs_span.lo, rhs.span.hi,
- ExprKind::Type(lhs, rhs), None);
+ let (lo, hi) = (lhs_span.lo, rhs.span.hi);
+ lhs = self.mk_expr(lo, hi, ExprKind::Type(lhs, rhs), ThinVec::new());
continue
} else if op == AssocOp::DotDot || op == AssocOp::DotDotDot {
// If we didn’t have to handle `x..`/`x...`, it would be pretty easy to
};
let r = try!(self.mk_range(Some(lhs), rhs, limits));
- lhs = self.mk_expr(lhs_span.lo, rhs_span.hi, r, None);
+ lhs = self.mk_expr(lhs_span.lo, rhs_span.hi, r, ThinVec::new());
break
}
}),
}?;
+ let (lo, hi) = (lhs_span.lo, rhs.span.hi);
lhs = match op {
AssocOp::Add | AssocOp::Subtract | AssocOp::Multiply | AssocOp::Divide |
AssocOp::Modulus | AssocOp::LAnd | AssocOp::LOr | AssocOp::BitXor |
AssocOp::Equal | AssocOp::Less | AssocOp::LessEqual | AssocOp::NotEqual |
AssocOp::Greater | AssocOp::GreaterEqual => {
let ast_op = op.to_ast_binop().unwrap();
- let (lhs_span, rhs_span) = (lhs_span, rhs.span);
let binary = self.mk_binary(codemap::respan(cur_op_span, ast_op), lhs, rhs);
- self.mk_expr(lhs_span.lo, rhs_span.hi, binary, None)
+ self.mk_expr(lo, hi, binary, ThinVec::new())
}
AssocOp::Assign =>
- self.mk_expr(lhs_span.lo, rhs.span.hi, ExprKind::Assign(lhs, rhs), None),
+ self.mk_expr(lo, hi, ExprKind::Assign(lhs, rhs), ThinVec::new()),
AssocOp::Inplace =>
- self.mk_expr(lhs_span.lo, rhs.span.hi, ExprKind::InPlace(lhs, rhs), None),
+ self.mk_expr(lo, hi, ExprKind::InPlace(lhs, rhs), ThinVec::new()),
AssocOp::AssignOp(k) => {
let aop = match k {
token::Plus => BinOpKind::Add,
token::Shl => BinOpKind::Shl,
token::Shr => BinOpKind::Shr,
};
- let (lhs_span, rhs_span) = (lhs_span, rhs.span);
let aopexpr = self.mk_assign_op(codemap::respan(cur_op_span, aop), lhs, rhs);
- self.mk_expr(lhs_span.lo, rhs_span.hi, aopexpr, None)
+ self.mk_expr(lo, hi, aopexpr, ThinVec::new())
}
AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotDot => {
self.bug("As, Colon, DotDot or DotDotDot branch reached")
/// Parse prefix-forms of range notation: `..expr`, `..`, `...expr`
fn parse_prefix_range_expr(&mut self,
- already_parsed_attrs: Option<ThinAttributes>)
+ already_parsed_attrs: Option<ThinVec<Attribute>>)
-> PResult<'a, P<Expr>> {
debug_assert!(self.token == token::DotDot || self.token == token::DotDotDot);
let tok = self.token.clone();
}
/// Parse an 'if' or 'if let' expression ('if' token already eaten)
- pub fn parse_if_expr(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
+ pub fn parse_if_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
if self.check_keyword(keywords::Let) {
return self.parse_if_let_expr(attrs);
}
}
/// Parse an 'if let' expression ('if' token already eaten)
- pub fn parse_if_let_expr(&mut self, attrs: ThinAttributes)
+ pub fn parse_if_let_expr(&mut self, attrs: ThinVec<Attribute>)
-> PResult<'a, P<Expr>> {
let lo = self.last_span.lo;
self.expect_keyword(keywords::Let)?;
pub fn parse_lambda_expr(&mut self,
lo: BytePos,
capture_clause: CaptureBy,
- attrs: ThinAttributes)
+ attrs: ThinVec<Attribute>)
-> PResult<'a, P<Expr>>
{
let decl = self.parse_fn_block_decl()?;
let body_expr = self.parse_expr()?;
P(ast::Block {
id: ast::DUMMY_NODE_ID,
- stmts: vec![],
span: body_expr.span,
- expr: Some(body_expr),
- stmts: vec![Spanned {
++ stmts: vec![Stmt {
+ span: body_expr.span,
- node: StmtKind::Expr(body_expr, ast::DUMMY_NODE_ID),
++ node: StmtKind::Expr(body_expr),
++ id: ast::DUMMY_NODE_ID,
+ }],
rules: BlockCheckMode::Default,
})
}
// `else` token already eaten
pub fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
if self.eat_keyword(keywords::If) {
- return self.parse_if_expr(None);
+ return self.parse_if_expr(ThinVec::new());
} else {
let blk = self.parse_block()?;
- return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprKind::Block(blk), None));
+ return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprKind::Block(blk), ThinVec::new()));
}
}
/// Parse a 'for' .. 'in' expression ('for' token already eaten)
pub fn parse_for_expr(&mut self, opt_ident: Option<ast::SpannedIdent>,
span_lo: BytePos,
- attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
+ mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
// Parse: `for <src_pat> in <src_expr> <src_loop_block>`
let pat = self.parse_pat()?;
self.expect_keyword(keywords::In)?;
let expr = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)?;
let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
- let attrs = attrs.append(iattrs.into_thin_attrs());
+ attrs.extend(iattrs);
let hi = self.last_span.hi;
/// Parse a 'while' or 'while let' expression ('while' token already eaten)
pub fn parse_while_expr(&mut self, opt_ident: Option<ast::SpannedIdent>,
span_lo: BytePos,
- attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
+ mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
if self.token.is_keyword(keywords::Let) {
return self.parse_while_let_expr(opt_ident, span_lo, attrs);
}
let cond = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)?;
let (iattrs, body) = self.parse_inner_attrs_and_block()?;
- let attrs = attrs.append(iattrs.into_thin_attrs());
+ attrs.extend(iattrs);
let hi = body.span.hi;
return Ok(self.mk_expr(span_lo, hi, ExprKind::While(cond, body, opt_ident),
attrs));
/// Parse a 'while let' expression ('while' token already eaten)
pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::SpannedIdent>,
span_lo: BytePos,
- attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
+ mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
self.expect_keyword(keywords::Let)?;
let pat = self.parse_pat()?;
self.expect(&token::Eq)?;
let expr = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)?;
let (iattrs, body) = self.parse_inner_attrs_and_block()?;
- let attrs = attrs.append(iattrs.into_thin_attrs());
+ attrs.extend(iattrs);
let hi = body.span.hi;
return Ok(self.mk_expr(span_lo, hi, ExprKind::WhileLet(pat, expr, body, opt_ident), attrs));
}
// parse `loop {...}`, `loop` token already eaten
pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::SpannedIdent>,
span_lo: BytePos,
- attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
+ mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
let (iattrs, body) = self.parse_inner_attrs_and_block()?;
- let attrs = attrs.append(iattrs.into_thin_attrs());
+ attrs.extend(iattrs);
let hi = body.span.hi;
Ok(self.mk_expr(span_lo, hi, ExprKind::Loop(body, opt_ident), attrs))
}
// `match` token already eaten
- fn parse_match_expr(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
+ fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
let match_span = self.last_span;
let lo = self.last_span.lo;
let discriminant = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL,
}
return Err(e)
}
- let attrs = attrs.append(
- self.parse_inner_attributes()?.into_thin_attrs());
+ attrs.extend(self.parse_inner_attributes()?);
+
let mut arms: Vec<Arm> = Vec::new();
while self.token != token::CloseDelim(token::Brace) {
match self.parse_arm() {
/// Parse an expression, subject to the given restrictions
pub fn parse_expr_res(&mut self, r: Restrictions,
- already_parsed_attrs: Option<ThinAttributes>)
+ already_parsed_attrs: Option<ThinVec<Attribute>>)
-> PResult<'a, P<Expr>> {
self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs))
}
}
/// Parse the fields of a struct-like pattern
- fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPat>> , bool)> {
+ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPat>>, bool)> {
let mut fields = Vec::new();
let mut etc = false;
let mut first = true;
};
fields.push(codemap::Spanned { span: mk_sp(lo, hi),
- node: ast::FieldPat { ident: fieldname,
- pat: subpat,
- is_shorthand: is_shorthand }});
+ node: ast::FieldPat { ident: fieldname,
+ pat: subpat,
+ is_shorthand: is_shorthand }});
}
return Ok((fields, etc));
}
(None, self.parse_path(PathStyle::Expr)?)
};
let hi = self.last_span.hi;
- Ok(self.mk_expr(lo, hi, ExprKind::Path(qself, path), None))
+ Ok(self.mk_expr(lo, hi, ExprKind::Path(qself, path), ThinVec::new()))
} else {
self.parse_pat_literal_maybe_minus()
}
let tts = self.parse_seq_to_end(
&token::CloseDelim(delim),
SeqSep::none(), |p| p.parse_token_tree())?;
- let mac = Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT };
+ let mac = Mac_ { path: path, tts: tts };
pat = PatKind::Mac(codemap::Spanned {node: mac,
- span: mk_sp(lo, self.last_span.hi)});
+ span: mk_sp(lo, self.last_span.hi)});
} else {
// Parse ident @ pat
// This can give false positives and parse nullary enums,
token::DotDotDot => {
// Parse range
let hi = self.last_span.hi;
- let begin = self.mk_expr(lo, hi, ExprKind::Path(qself, path), None);
+ let begin =
+ self.mk_expr(lo, hi, ExprKind::Path(qself, path), ThinVec::new());
self.bump();
let end = self.parse_pat_range_end()?;
pat = PatKind::Range(begin, end);
pat = PatKind::TupleStruct(path, fields, ddpos)
}
_ => {
- pat = match qself {
- // Parse qualified path
- Some(qself) => PatKind::QPath(qself, path),
- // Parse nullary enum
- None => PatKind::Path(path)
- };
+ pat = PatKind::Path(qself, path);
}
}
}
}
/// Parse a local variable declaration
- fn parse_local(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Local>> {
+ fn parse_local(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Local>> {
let lo = self.span.lo;
let pat = self.parse_pat()?;
}))
}
- /// Parse a "let" stmt
- fn parse_let(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Decl>> {
- let lo = self.span.lo;
- let local = self.parse_local(attrs)?;
- Ok(P(spanned(lo, self.last_span.hi, DeclKind::Local(local))))
- }
-
/// Parse a structure field
fn parse_name_and_ty(&mut self, pr: Visibility,
attrs: Vec<Attribute> ) -> PResult<'a, StructField> {
let attrs = self.parse_outer_attributes()?;
let lo = self.span.lo;
- Ok(Some(if self.check_keyword(keywords::Let) {
- self.expect_keyword(keywords::Let)?;
- let decl = self.parse_let(attrs.into_thin_attrs())?;
- let hi = decl.span.hi;
- let stmt = StmtKind::Decl(decl, ast::DUMMY_NODE_ID);
- spanned(lo, hi, stmt)
+ Ok(Some(if self.eat_keyword(keywords::Let) {
+ Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: StmtKind::Local(self.parse_local(attrs.into())?),
+ span: mk_sp(lo, self.last_span.hi),
+ }
} else if self.token.is_ident()
&& !self.token.is_any_keyword()
&& self.look_ahead(1, |t| *t == token::Not) {
};
if id.name == keywords::Invalid.name() {
- let mac = P(spanned(lo, hi, Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT }));
- let stmt = StmtKind::Mac(mac, style, attrs.into_thin_attrs());
- spanned(lo, hi, stmt)
+ let mac = spanned(lo, hi, Mac_ { path: pth, tts: tts });
+ Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: StmtKind::Mac(P((mac, style, attrs.into()))),
+ span: mk_sp(lo, hi),
+ }
} else {
// if it has a special ident, it's definitely an item
//
followed by a semicolon");
}
}
- spanned(lo, hi, StmtKind::Decl(
- P(spanned(lo, hi, DeclKind::Item(
+ Stmt {
+ id: ast::DUMMY_NODE_ID,
+ span: mk_sp(lo, hi),
+ node: StmtKind::Item({
self.mk_item(
lo, hi, id /*id is good here*/,
- ItemKind::Mac(spanned(lo, hi,
- Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })),
- Visibility::Inherited, attrs)))),
- ast::DUMMY_NODE_ID))
+ ItemKind::Mac(spanned(lo, hi, Mac_ { path: pth, tts: tts })),
+ Visibility::Inherited,
+ attrs)
+ }),
+ }
}
} else {
// FIXME: Bad copy of attrs
let restrictions = self.restrictions | Restrictions::NO_NONINLINE_MOD;
match self.with_res(restrictions,
|this| this.parse_item_(attrs.clone(), false, true))? {
- Some(i) => {
- let hi = i.span.hi;
- let decl = P(spanned(lo, hi, DeclKind::Item(i)));
- spanned(lo, hi, StmtKind::Decl(decl, ast::DUMMY_NODE_ID))
- }
+ Some(i) => Stmt {
+ id: ast::DUMMY_NODE_ID,
+ span: mk_sp(lo, i.span.hi),
+ node: StmtKind::Item(i),
+ },
None => {
let unused_attrs = |attrs: &[_], s: &mut Self| {
if attrs.len() > 0 {
// Remainder are line-expr stmts.
let e = self.parse_expr_res(
- Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into_thin_attrs()))?;
- let hi = e.span.hi;
- let stmt = StmtKind::Expr(e, ast::DUMMY_NODE_ID);
- spanned(lo, hi, stmt)
+ Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into()))?;
+ Stmt {
+ id: ast::DUMMY_NODE_ID,
+ span: mk_sp(lo, e.span.hi),
+ node: StmtKind::Expr(e),
+ }
}
}
}))
/// Precondition: already parsed the '{'.
fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<'a, P<Block>> {
let mut stmts = vec![];
- let mut expr = None;
while !self.eat(&token::CloseDelim(token::Brace)) {
- let Spanned {node, span} = if let Some(s) = self.parse_stmt_() {
+ let Stmt {node, span, ..} = if let Some(s) = self.parse_stmt_() {
s
} else if self.token == token::Eof {
break;
// Found only `;` or `}`.
continue;
};
+
match node {
- StmtKind::Expr(e, _) => {
+ StmtKind::Expr(e) => {
- self.handle_expression_like_statement(e, span, &mut stmts, &mut expr)?;
+ self.handle_expression_like_statement(e, span, &mut stmts)?;
}
- StmtKind::Mac(mac, MacStmtStyle::NoBraces, attrs) => {
- // statement macro without braces
- match self.token {
- token::Semi => {
- stmts.push(Spanned {
- node: StmtKind::Mac(mac, MacStmtStyle::Semicolon, attrs),
- span: mk_sp(span.lo, self.span.hi),
- });
- self.bump();
- }
- _ => {
- let e = self.mk_mac_expr(span.lo, span.hi,
- mac.and_then(|m| m.node),
- None);
- let lo = e.span.lo;
- let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?;
- let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
- self.handle_expression_like_statement(e, span, &mut stmts)?;
- }
- }
- }
- StmtKind::Mac(m, style, attrs) => {
- // statement macro; might be an expr
- match self.token {
- token::Semi => {
- stmts.push(Spanned {
- node: StmtKind::Mac(m, MacStmtStyle::Semicolon, attrs),
- span: mk_sp(span.lo, self.span.hi),
- });
- self.bump();
- }
- _ => {
- stmts.push(Spanned {
- node: StmtKind::Mac(m, style, attrs),
- span: span
- });
- }
- }
+ StmtKind::Mac(mac) => {
- self.handle_macro_in_block(mac.unwrap(), span, &mut stmts, &mut expr)?;
++ self.handle_macro_in_block(mac.unwrap(), span, &mut stmts)?;
}
_ => { // all other kinds of statements:
let mut hi = span.hi;
hi = self.last_span.hi;
}
- stmts.push(Spanned {
+ stmts.push(Stmt {
+ id: ast::DUMMY_NODE_ID,
node: node,
span: mk_sp(span.lo, hi)
});
Ok(P(ast::Block {
stmts: stmts,
- expr: expr,
id: ast::DUMMY_NODE_ID,
rules: s,
span: mk_sp(lo, self.last_span.hi),
}))
}
- stmts: &mut Vec<Stmt>,
- last_block_expr: &mut Option<P<Expr>>)
+ fn handle_macro_in_block(&mut self,
+ (mac, style, attrs): (ast::Mac, MacStmtStyle, ThinVec<Attribute>),
+ span: Span,
- self.handle_expression_like_statement(e, span, stmts, last_block_expr)?;
++ stmts: &mut Vec<Stmt>)
+ -> PResult<'a, ()> {
+ if style == MacStmtStyle::NoBraces {
+ // statement macro without braces; might be an
+ // expr depending on whether a semicolon follows
+ match self.token {
+ token::Semi => {
+ stmts.push(Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: StmtKind::Mac(P((mac, MacStmtStyle::Semicolon, attrs))),
+ span: mk_sp(span.lo, self.span.hi),
+ });
+ self.bump();
+ }
+ _ => {
+ let e = self.mk_mac_expr(span.lo, span.hi, mac.node, ThinVec::new());
+ let lo = e.span.lo;
+ let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?;
+ let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
- token::CloseDelim(token::Brace) => {
- // if a block ends in `m!(arg)` without
- // a `;`, it must be an expr
- *last_block_expr = Some(self.mk_mac_expr(span.lo, span.hi, mac.node, attrs));
- }
++ self.handle_expression_like_statement(e, span, stmts)?;
+ }
+ }
+ } else {
+ // statement macro; might be an expr
+ match self.token {
+ token::Semi => {
+ stmts.push(Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: StmtKind::Mac(P((mac, MacStmtStyle::Semicolon, attrs))),
+ span: mk_sp(span.lo, self.span.hi),
+ });
+ self.bump();
+ }
+ _ => {
+ stmts.push(Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: StmtKind::Mac(P((mac, style, attrs))),
+ span: span
+ });
+ }
+ }
+ }
+ Ok(())
+ }
+
fn handle_expression_like_statement(&mut self,
e: P<Expr>,
span: Span,
- stmts: &mut Vec<Stmt>,
- last_block_expr: &mut Option<P<Expr>>)
+ stmts: &mut Vec<Stmt>)
-> PResult<'a, ()> {
// expression without semicolon
if classify::expr_requires_semi_to_be_stmt(&e) {
hi: self.last_span.hi,
expn_id: span.expn_id,
};
- stmts.push(Spanned {
- node: StmtKind::Semi(e, ast::DUMMY_NODE_ID),
+ stmts.push(Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: StmtKind::Semi(e),
span: span_with_semi,
});
}
- token::CloseDelim(token::Brace) => *last_block_expr = Some(e),
_ => {
- stmts.push(Spanned {
- node: StmtKind::Expr(e, ast::DUMMY_NODE_ID),
+ stmts.push(Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: StmtKind::Expr(e),
span: span
});
}
let tts = self.parse_seq_to_end(&token::CloseDelim(delim),
SeqSep::none(),
|p| p.parse_token_tree())?;
- let m_ = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
+ let m_ = Mac_ { path: pth, tts: tts };
let m: ast::Mac = codemap::Spanned { node: m_,
- span: mk_sp(lo,
- self.last_span.hi) };
+ span: mk_sp(lo,
+ self.last_span.hi) };
if delim != token::Brace {
self.expect(&token::Semi)?
}
/// Parse trait Foo { ... }
fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
-
let ident = self.parse_ident()?;
let mut tps = self.parse_generics()?;
return Err(self.fatal(&format!("expected item, found `{}`", token_str)));
}
- let hi = if self.span == codemap::DUMMY_SP {
+ let hi = if self.span == syntax_pos::DUMMY_SP {
inner_lo
} else {
self.last_span.hi
SeqSep::none(),
|p| p.parse_token_tree())?;
// single-variant-enum... :
- let m = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
+ let m = Mac_ { path: pth, tts: tts };
let m: ast::Mac = codemap::Spanned { node: m,
- span: mk_sp(mac_lo,
- self.last_span.hi) };
+ span: mk_sp(mac_lo,
+ self.last_span.hi) };
if delim != token::Brace {
if !self.eat(&token::Semi) {
pub use self::AnnNode::*;
use abi::{self, Abi};
-use ast::{self, TokenTree, BlockCheckMode, PatKind};
+use ast::{self, BlockCheckMode, PatKind};
use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
use ast::Attribute;
-use attr::ThinAttributesExt;
use util::parser::AssocOp;
use attr;
use attr::{AttrMetaMethods, AttributeMethods};
-use codemap::{self, CodeMap, BytePos};
+use codemap::{self, CodeMap};
+use syntax_pos::{self, BytePos};
use errors;
use parse::token::{self, keywords, BinOpToken, Token, InternedString};
use parse::lexer::comments;
use print::pp::Breaks::{Consistent, Inconsistent};
use ptr::P;
use std_inject;
+use tokenstream::{self, TokenTree};
use std::ascii;
use std::io::{self, Write, Read};
to_string(|s| s.print_lifetime(e))
}
-pub fn tt_to_string(tt: &ast::TokenTree) -> String {
+pub fn tt_to_string(tt: &tokenstream::TokenTree) -> String {
to_string(|s| s.print_tt(tt))
}
-pub fn tts_to_string(tts: &[ast::TokenTree]) -> String {
+pub fn tts_to_string(tts: &[tokenstream::TokenTree]) -> String {
to_string(|s| s.print_tts(tts))
}
self.end() // close the head-box
}
- pub fn bclose_(&mut self, span: codemap::Span,
+ pub fn bclose_(&mut self, span: syntax_pos::Span,
indented: usize) -> io::Result<()> {
self.bclose_maybe_open(span, indented, true)
}
- pub fn bclose_maybe_open(&mut self, span: codemap::Span,
+ pub fn bclose_maybe_open(&mut self, span: syntax_pos::Span,
indented: usize, close_box: bool) -> io::Result<()> {
try!(self.maybe_print_comment(span.hi));
try!(self.break_offset_if_not_bol(1, -(indented as isize)));
}
Ok(())
}
- pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> {
+ pub fn bclose(&mut self, span: syntax_pos::Span) -> io::Result<()> {
self.bclose_(span, INDENT_UNIT)
}
mut op: F,
mut get_span: G) -> io::Result<()> where
F: FnMut(&mut State, &T) -> io::Result<()>,
- G: FnMut(&T) -> codemap::Span,
+ G: FnMut(&T) -> syntax_pos::Span,
{
try!(self.rbox(0, b));
let len = elts.len();
pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
generics: &ast::Generics, ident: ast::Ident,
- span: codemap::Span,
+ span: syntax_pos::Span,
visibility: &ast::Visibility) -> io::Result<()> {
try!(self.head(&visibility_qualified(visibility, "enum")));
try!(self.print_ident(ident));
pub fn print_variants(&mut self,
variants: &[ast::Variant],
- span: codemap::Span) -> io::Result<()> {
+ span: syntax_pos::Span) -> io::Result<()> {
try!(self.bopen());
for v in variants {
try!(self.space_if_not_bol());
struct_def: &ast::VariantData,
generics: &ast::Generics,
ident: ast::Ident,
- span: codemap::Span,
+ span: syntax_pos::Span,
print_finalizer: bool) -> io::Result<()> {
try!(self.print_ident(ident));
try!(self.print_generics(generics));
/// appropriate macro, transcribe back into the grammar we just parsed from,
/// and then pretty-print the resulting AST nodes (so, e.g., we print
/// expression arguments as expressions). It can be done! I think.
- pub fn print_tt(&mut self, tt: &ast::TokenTree) -> io::Result<()> {
+ pub fn print_tt(&mut self, tt: &tokenstream::TokenTree) -> io::Result<()> {
match *tt {
TokenTree::Token(_, ref tk) => {
try!(word(&mut self.s, &token_to_string(tk)));
None => {},
}
match seq.op {
- ast::KleeneOp::ZeroOrMore => word(&mut self.s, "*"),
- ast::KleeneOp::OneOrMore => word(&mut self.s, "+"),
+ tokenstream::KleeneOp::ZeroOrMore => word(&mut self.s, "*"),
+ tokenstream::KleeneOp::OneOrMore => word(&mut self.s, "+"),
}
}
}
}
- pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> io::Result<()> {
+ pub fn print_tts(&mut self, tts: &[tokenstream::TokenTree]) -> io::Result<()> {
try!(self.ibox(0));
for (i, tt) in tts.iter().enumerate() {
if i != 0 {
try!(self.print_associated_type(ti.ident, Some(bounds),
default.as_ref().map(|ty| &**ty)));
}
+ ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => {
+ // code copied from ItemKind::Mac:
+ self.print_path(&node.path, false, 0)?;
+ word(&mut self.s, "! ")?;
+ self.cbox(INDENT_UNIT)?;
+ self.popen()?;
+ self.print_tts(&node.tts[..])?;
+ self.pclose()?;
+ word(&mut self.s, ";")?;
+ self.end()?
+ }
}
self.ann.post(self, NodeSubItem(ti.id))
}
pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> {
try!(self.maybe_print_comment(st.span.lo));
match st.node {
- ast::StmtKind::Decl(ref decl, _) => {
- try!(self.print_decl(&decl));
+ ast::StmtKind::Local(ref loc) => {
+ try!(self.print_outer_attributes(&loc.attrs));
+ try!(self.space_if_not_bol());
+ try!(self.ibox(INDENT_UNIT));
+ try!(self.word_nbsp("let"));
+
+ try!(self.ibox(INDENT_UNIT));
+ try!(self.print_local_decl(&loc));
+ try!(self.end());
+ if let Some(ref init) = loc.init {
+ try!(self.nbsp());
+ try!(self.word_space("="));
+ try!(self.print_expr(&init));
+ }
++ try!(word(&mut self.s, ";"));
+ self.end()?;
}
- ast::StmtKind::Expr(ref expr, _) => {
+ ast::StmtKind::Item(ref item) => self.print_item(&item)?,
+ ast::StmtKind::Expr(ref expr) => {
try!(self.space_if_not_bol());
try!(self.print_expr_outer_attr_style(&expr, false));
+ if parse::classify::expr_requires_semi_to_be_stmt(expr) {
+ try!(word(&mut self.s, ";"));
+ }
}
- ast::StmtKind::Semi(ref expr, _) => {
+ ast::StmtKind::Semi(ref expr) => {
try!(self.space_if_not_bol());
try!(self.print_expr_outer_attr_style(&expr, false));
try!(word(&mut self.s, ";"));
}
- ast::StmtKind::Mac(ref mac, style, ref attrs) => {
+ ast::StmtKind::Mac(ref mac) => {
+ let (ref mac, style, ref attrs) = **mac;
try!(self.space_if_not_bol());
- try!(self.print_outer_attributes(attrs.as_attr_slice()));
+ try!(self.print_outer_attributes(&attrs));
let delim = match style {
ast::MacStmtStyle::Braces => token::Brace,
_ => token::Paren
}
}
}
- if parse::classify::stmt_ends_with_semi(&st.node) {
- try!(word(&mut self.s, ";"));
- }
self.maybe_print_trailing_comment(st.span, None)
}
try!(self.print_inner_attributes(attrs));
- for st in &blk.stmts {
- try!(self.print_stmt(st));
- }
- match blk.expr {
- Some(ref expr) => {
- try!(self.space_if_not_bol());
- try!(self.print_expr_outer_attr_style(&expr, false));
- try!(self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi)));
+ for (i, st) in blk.stmts.iter().enumerate() {
+ match st.node {
- ast::StmtKind::Expr(ref expr, _) if i == blk.stmts.len() - 1 => {
++ ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => {
+ try!(self.space_if_not_bol());
+ try!(self.print_expr_outer_attr_style(&expr, false));
+ try!(self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi)));
+ }
+ _ => try!(self.print_stmt(st)),
}
- _ => ()
}
+
try!(self.bclose_maybe_open(blk.span, indented, close_box));
self.ann.post(self, NodeBlock(blk))
}
is_inline: bool) -> io::Result<()> {
try!(self.maybe_print_comment(expr.span.lo));
- let attrs = expr.attrs.as_attr_slice();
+ let attrs = &expr.attrs;
if is_inline {
try!(self.print_outer_attributes_inline(attrs));
} else {
_ => false
};
- if !default_return || !body.stmts.is_empty() || body.expr.is_none() {
- try!(self.print_block_unclosed(&body));
- } else {
- // we extract the block, so as not to create another set of boxes
- let i_expr = body.expr.as_ref().unwrap();
- match i_expr.node {
- ast::ExprKind::Block(ref blk) => {
+ match body.stmts.last().map(|stmt| &stmt.node) {
- Some(&ast::StmtKind::Expr(ref i_expr, _)) if default_return &&
- body.stmts.len() == 1 => {
++ Some(&ast::StmtKind::Expr(ref i_expr)) if default_return &&
++ body.stmts.len() == 1 => {
+ // we extract the block, so as not to create another set of boxes
+ if let ast::ExprKind::Block(ref blk) = i_expr.node {
- try!(self.print_block_unclosed_with_attrs(
- &blk,
- i_expr.attrs.as_attr_slice()));
+ try!(self.print_block_unclosed_with_attrs(&blk, &i_expr.attrs));
- }
- _ => {
+ } else {
// this is a bare expression
try!(self.print_expr(&i_expr));
try!(self.end()); // need to close a box
}
}
+ _ => try!(self.print_block_unclosed(&body)),
}
+
// a box will be closed by print_expr, but we didn't want an overall
// wrapper so we closed the corresponding opening. so create an
// empty box to satisfy the close.
try!(space(&mut self.s));
}
}
- ast::ExprKind::Again(opt_ident) => {
+ ast::ExprKind::Continue(opt_ident) => {
try!(word(&mut self.s, "continue"));
try!(space(&mut self.s));
if let Some(ident) = opt_ident {
Ok(())
}
- pub fn print_decl(&mut self, decl: &ast::Decl) -> io::Result<()> {
- try!(self.maybe_print_comment(decl.span.lo));
- match decl.node {
- ast::DeclKind::Local(ref loc) => {
- try!(self.print_outer_attributes(loc.attrs.as_attr_slice()));
- try!(self.space_if_not_bol());
- try!(self.ibox(INDENT_UNIT));
- try!(self.word_nbsp("let"));
-
- try!(self.ibox(INDENT_UNIT));
- try!(self.print_local_decl(&loc));
- try!(self.end());
- if let Some(ref init) = loc.init {
- try!(self.nbsp());
- try!(self.word_space("="));
- try!(self.print_expr(&init));
- }
- try!(word(&mut self.s, ";"));
- self.end()
- }
- ast::DeclKind::Item(ref item) => self.print_item(&item)
- }
- }
-
pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
try!(word(&mut self.s, &ident.name.as_str()));
self.ann.post(self, NodeIdent(&ident))
}
try!(self.pclose());
}
- PatKind::Path(ref path) => {
+ PatKind::Path(None, ref path) => {
try!(self.print_path(path, true, 0));
}
- PatKind::QPath(ref qself, ref path) => {
+ PatKind::Path(Some(ref qself), ref path) => {
try!(self.print_qpath(path, qself, false));
}
PatKind::Struct(ref path, ref fields, etc) => {
self.end()
}
- pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span,
+ pub fn maybe_print_trailing_comment(&mut self, span: syntax_pos::Span,
next_pos: Option<BytePos>)
-> io::Result<()> {
let cm = match self.cm {
use ast;
use codemap;
use parse::token;
+ use syntax_pos;
#[test]
fn test_fun_to_string() {
let decl = ast::FnDecl {
inputs: Vec::new(),
- output: ast::FunctionRetTy::Default(codemap::DUMMY_SP),
+ output: ast::FunctionRetTy::Default(syntax_pos::DUMMY_SP),
variadic: false
};
let generics = ast::Generics::default();
fn test_variant_to_string() {
let ident = token::str_to_ident("principal_skinner");
- let var = codemap::respan(codemap::DUMMY_SP, ast::Variant_ {
+ let var = codemap::respan(syntax_pos::DUMMY_SP, ast::Variant_ {
name: ident,
attrs: Vec::new(),
// making this up as I go.... ?
#![allow(dead_code)]
#![allow(unused_imports)]
+
use self::HasTestSignature::*;
use std::iter;
use std::vec;
use attr::AttrMetaMethods;
use attr;
-use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
-use codemap;
+use syntax_pos::{self, DUMMY_SP, NO_EXPANSION, Span, FileMap, BytePos};
+use std::rc::Rc;
+
+use codemap::{self, CodeMap, ExpnInfo, NameAndSpan, MacroAttribute};
use errors;
+use errors::snippet::{RenderedLine, SnippetData};
use config;
use entry::{self, EntryPointType};
use ext::base::{ExtCtxt, DummyMacroLoader};
let main_attr = ecx.attribute(sp, main_meta);
// pub fn main() { ... }
let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![]));
- let main_body = ecx.block_all(sp, vec![call_test_main], None);
+ let main_body = ecx.block(sp, vec![call_test_main]);
let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], main_ret_ty),
ast::Unsafety::Normal,
ast::Constness::NotConst,
mk_test_desc_and_fn_rec(cx, test)
}).collect()),
span: DUMMY_SP,
- attrs: None,
+ attrs: ast::ThinVec::new(),
})),
span: DUMMY_SP,
- attrs: None,
+ attrs: ast::ThinVec::new(),
})
}
use abi::Abi;
use ast::*;
-use attr::ThinAttributesExt;
-use codemap::{Span, Spanned};
+use syntax_pos::Span;
+use codemap::Spanned;
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum FnKind<'a> {
/// explicitly, you need to override each method. (And you also need
/// to monitor future changes to `Visitor` in case a new method with a
/// new default implementation gets introduced.)
-pub trait Visitor<'v> : Sized {
+pub trait Visitor: Sized {
fn visit_name(&mut self, _span: Span, _name: Name) {
// Nothing to do.
}
fn visit_ident(&mut self, span: Span, ident: Ident) {
walk_ident(self, span, ident);
}
- fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
- fn visit_foreign_item(&mut self, i: &'v ForeignItem) { walk_foreign_item(self, i) }
- fn visit_item(&mut self, i: &'v Item) { walk_item(self, i) }
- fn visit_local(&mut self, l: &'v Local) { walk_local(self, l) }
- fn visit_block(&mut self, b: &'v Block) { walk_block(self, b) }
- fn visit_stmt(&mut self, s: &'v Stmt) { walk_stmt(self, s) }
- fn visit_arm(&mut self, a: &'v Arm) { walk_arm(self, a) }
- fn visit_pat(&mut self, p: &'v Pat) { walk_pat(self, p) }
- fn visit_decl(&mut self, d: &'v Decl) { walk_decl(self, d) }
- fn visit_expr(&mut self, ex: &'v Expr) { walk_expr(self, ex) }
- fn visit_expr_post(&mut self, _ex: &'v Expr) { }
- fn visit_ty(&mut self, t: &'v Ty) { walk_ty(self, t) }
- fn visit_generics(&mut self, g: &'v Generics) { walk_generics(self, g) }
- fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) {
+ fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
+ fn visit_foreign_item(&mut self, i: &ForeignItem) { walk_foreign_item(self, i) }
+ fn visit_item(&mut self, i: &Item) { walk_item(self, i) }
+ fn visit_local(&mut self, l: &Local) { walk_local(self, l) }
+ fn visit_block(&mut self, b: &Block) { walk_block(self, b) }
+ fn visit_stmt(&mut self, s: &Stmt) { walk_stmt(self, s) }
+ fn visit_arm(&mut self, a: &Arm) { walk_arm(self, a) }
+ fn visit_pat(&mut self, p: &Pat) { walk_pat(self, p) }
+ fn visit_expr(&mut self, ex: &Expr) { walk_expr(self, ex) }
+ fn visit_expr_post(&mut self, _ex: &Expr) { }
+ fn visit_ty(&mut self, t: &Ty) { walk_ty(self, t) }
+ fn visit_generics(&mut self, g: &Generics) { walk_generics(self, g) }
+ fn visit_fn(&mut self, fk: FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId) {
walk_fn(self, fk, fd, b, s)
}
- fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) }
- fn visit_impl_item(&mut self, ii: &'v ImplItem) { walk_impl_item(self, ii) }
- fn visit_trait_ref(&mut self, t: &'v TraitRef) { walk_trait_ref(self, t) }
- fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
+ fn visit_trait_item(&mut self, ti: &TraitItem) { walk_trait_item(self, ti) }
+ fn visit_impl_item(&mut self, ii: &ImplItem) { walk_impl_item(self, ii) }
+ fn visit_trait_ref(&mut self, t: &TraitRef) { walk_trait_ref(self, t) }
+ fn visit_ty_param_bound(&mut self, bounds: &TyParamBound) {
walk_ty_param_bound(self, bounds)
}
- fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
+ fn visit_poly_trait_ref(&mut self, t: &PolyTraitRef, m: &TraitBoundModifier) {
walk_poly_trait_ref(self, t, m)
}
- fn visit_variant_data(&mut self, s: &'v VariantData, _: Ident,
- _: &'v Generics, _: NodeId, _: Span) {
+ fn visit_variant_data(&mut self, s: &VariantData, _: Ident,
+ _: &Generics, _: NodeId, _: Span) {
walk_struct_def(self, s)
}
- fn visit_struct_field(&mut self, s: &'v StructField) { walk_struct_field(self, s) }
- fn visit_enum_def(&mut self, enum_definition: &'v EnumDef,
- generics: &'v Generics, item_id: NodeId, _: Span) {
+ fn visit_struct_field(&mut self, s: &StructField) { walk_struct_field(self, s) }
+ fn visit_enum_def(&mut self, enum_definition: &EnumDef,
+ generics: &Generics, item_id: NodeId, _: Span) {
walk_enum_def(self, enum_definition, generics, item_id)
}
- fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
+ fn visit_variant(&mut self, v: &Variant, g: &Generics, item_id: NodeId) {
walk_variant(self, v, g, item_id)
}
- fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
+ fn visit_lifetime(&mut self, lifetime: &Lifetime) {
walk_lifetime(self, lifetime)
}
- fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
+ fn visit_lifetime_def(&mut self, lifetime: &LifetimeDef) {
walk_lifetime_def(self, lifetime)
}
- fn visit_mac(&mut self, _mac: &'v Mac) {
+ fn visit_mac(&mut self, _mac: &Mac) {
panic!("visit_mac disabled by default");
// NB: see note about macros above.
// if you really want a visitor that
// definition in your trait impl:
// visit::walk_mac(self, _mac)
}
- fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
+ fn visit_path(&mut self, path: &Path, _id: NodeId) {
walk_path(self, path)
}
- fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
+ fn visit_path_list_item(&mut self, prefix: &Path, item: &PathListItem) {
walk_path_list_item(self, prefix, item)
}
- fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
+ fn visit_path_segment(&mut self, path_span: Span, path_segment: &PathSegment) {
walk_path_segment(self, path_span, path_segment)
}
- fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
+ fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &PathParameters) {
walk_path_parameters(self, path_span, path_parameters)
}
- fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) {
+ fn visit_assoc_type_binding(&mut self, type_binding: &TypeBinding) {
walk_assoc_type_binding(self, type_binding)
}
- fn visit_attribute(&mut self, _attr: &'v Attribute) {}
- fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
+ fn visit_attribute(&mut self, _attr: &Attribute) {}
+ fn visit_macro_def(&mut self, macro_def: &MacroDef) {
walk_macro_def(self, macro_def)
}
- fn visit_vis(&mut self, vis: &'v Visibility) {
+ fn visit_vis(&mut self, vis: &Visibility) {
walk_vis(self, vis)
}
}
}
}
-pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
+pub fn walk_opt_name<V: Visitor>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
if let Some(name) = opt_name {
visitor.visit_name(span, name);
}
}
-pub fn walk_opt_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_ident: Option<Ident>) {
+pub fn walk_opt_ident<V: Visitor>(visitor: &mut V, span: Span, opt_ident: Option<Ident>) {
if let Some(ident) = opt_ident {
visitor.visit_ident(span, ident);
}
}
-pub fn walk_opt_sp_ident<'v, V: Visitor<'v>>(visitor: &mut V,
- opt_sp_ident: &Option<Spanned<Ident>>) {
+pub fn walk_opt_sp_ident<V: Visitor>(visitor: &mut V, opt_sp_ident: &Option<Spanned<Ident>>) {
if let Some(ref sp_ident) = *opt_sp_ident {
visitor.visit_ident(sp_ident.span, sp_ident.node);
}
}
-pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, ident: Ident) {
+pub fn walk_ident<V: Visitor>(visitor: &mut V, span: Span, ident: Ident) {
visitor.visit_name(span, ident.name);
}
-pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
+pub fn walk_crate<V: Visitor>(visitor: &mut V, krate: &Crate) {
visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
walk_list!(visitor, visit_attribute, &krate.attrs);
walk_list!(visitor, visit_macro_def, &krate.exported_macros);
}
-pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) {
+pub fn walk_macro_def<V: Visitor>(visitor: &mut V, macro_def: &MacroDef) {
visitor.visit_ident(macro_def.span, macro_def.ident);
walk_opt_ident(visitor, macro_def.span, macro_def.imported_from);
walk_list!(visitor, visit_attribute, ¯o_def.attrs);
}
-pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) {
+pub fn walk_mod<V: Visitor>(visitor: &mut V, module: &Mod) {
walk_list!(visitor, visit_item, &module.items);
}
-pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
- for attr in local.attrs.as_attr_slice() {
+pub fn walk_local<V: Visitor>(visitor: &mut V, local: &Local) {
+ for attr in local.attrs.iter() {
visitor.visit_attribute(attr);
}
visitor.visit_pat(&local.pat);
walk_list!(visitor, visit_expr, &local.init);
}
-pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
+pub fn walk_lifetime<V: Visitor>(visitor: &mut V, lifetime: &Lifetime) {
visitor.visit_name(lifetime.span, lifetime.name);
}
-pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V,
- lifetime_def: &'v LifetimeDef) {
+pub fn walk_lifetime_def<V: Visitor>(visitor: &mut V, lifetime_def: &LifetimeDef) {
visitor.visit_lifetime(&lifetime_def.lifetime);
walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
}
-pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
- trait_ref: &'v PolyTraitRef,
- _modifier: &'v TraitBoundModifier)
- where V: Visitor<'v>
+pub fn walk_poly_trait_ref<V>(visitor: &mut V, trait_ref: &PolyTraitRef, _: &TraitBoundModifier)
+ where V: Visitor,
{
walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes);
visitor.visit_trait_ref(&trait_ref.trait_ref);
}
-pub fn walk_trait_ref<'v,V>(visitor: &mut V,
- trait_ref: &'v TraitRef)
- where V: Visitor<'v>
-{
+pub fn walk_trait_ref<V: Visitor>(visitor: &mut V, trait_ref: &TraitRef) {
visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
}
-pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
+pub fn walk_item<V: Visitor>(visitor: &mut V, item: &Item) {
visitor.visit_vis(&item.vis);
visitor.visit_ident(item.span, item.ident);
match item.node {
walk_list!(visitor, visit_attribute, &item.attrs);
}
-pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
- enum_definition: &'v EnumDef,
- generics: &'v Generics,
- item_id: NodeId) {
+pub fn walk_enum_def<V: Visitor>(visitor: &mut V,
+ enum_definition: &EnumDef,
+ generics: &Generics,
+ item_id: NodeId) {
walk_list!(visitor, visit_variant, &enum_definition.variants, generics, item_id);
}
-pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
- variant: &'v Variant,
- generics: &'v Generics,
- item_id: NodeId) {
+pub fn walk_variant<V>(visitor: &mut V, variant: &Variant, generics: &Generics, item_id: NodeId)
+ where V: Visitor,
+{
visitor.visit_ident(variant.span, variant.node.name);
visitor.visit_variant_data(&variant.node.data, variant.node.name,
generics, item_id, variant.span);
walk_list!(visitor, visit_attribute, &variant.node.attrs);
}
-pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
+pub fn walk_ty<V: Visitor>(visitor: &mut V, typ: &Ty) {
match typ.node {
TyKind::Vec(ref ty) | TyKind::Paren(ref ty) => {
visitor.visit_ty(ty)
}
}
-pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
+pub fn walk_path<V: Visitor>(visitor: &mut V, path: &Path) {
for segment in &path.segments {
visitor.visit_path_segment(path.span, segment);
}
}
-pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V, _prefix: &'v Path,
- item: &'v PathListItem) {
+pub fn walk_path_list_item<V: Visitor>(visitor: &mut V, _prefix: &Path, item: &PathListItem) {
walk_opt_ident(visitor, item.span, item.node.name());
walk_opt_ident(visitor, item.span, item.node.rename());
}
-pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
- path_span: Span,
- segment: &'v PathSegment) {
+pub fn walk_path_segment<V: Visitor>(visitor: &mut V, path_span: Span, segment: &PathSegment) {
visitor.visit_ident(path_span, segment.identifier);
visitor.visit_path_parameters(path_span, &segment.parameters);
}
-pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
- _path_span: Span,
- path_parameters: &'v PathParameters) {
+pub fn walk_path_parameters<V>(visitor: &mut V, _path_span: Span, path_parameters: &PathParameters)
+ where V: Visitor,
+{
match *path_parameters {
PathParameters::AngleBracketed(ref data) => {
walk_list!(visitor, visit_ty, &data.types);
}
}
-pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
- type_binding: &'v TypeBinding) {
+pub fn walk_assoc_type_binding<V: Visitor>(visitor: &mut V, type_binding: &TypeBinding) {
visitor.visit_ident(type_binding.span, type_binding.ident);
visitor.visit_ty(&type_binding.ty);
}
-pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
+pub fn walk_pat<V: Visitor>(visitor: &mut V, pattern: &Pat) {
match pattern.node {
PatKind::TupleStruct(ref path, ref children, _) => {
visitor.visit_path(path, pattern.id);
walk_list!(visitor, visit_pat, children);
}
- PatKind::Path(ref path) => {
- visitor.visit_path(path, pattern.id);
- }
- PatKind::QPath(ref qself, ref path) => {
- visitor.visit_ty(&qself.ty);
+ PatKind::Path(ref opt_qself, ref path) => {
+ if let Some(ref qself) = *opt_qself {
+ visitor.visit_ty(&qself.ty);
+ }
visitor.visit_path(path, pattern.id)
}
PatKind::Struct(ref path, ref fields, _) => {
}
}
-pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V,
- foreign_item: &'v ForeignItem) {
+pub fn walk_foreign_item<V: Visitor>(visitor: &mut V, foreign_item: &ForeignItem) {
visitor.visit_vis(&foreign_item.vis);
visitor.visit_ident(foreign_item.span, foreign_item.ident);
walk_list!(visitor, visit_attribute, &foreign_item.attrs);
}
-pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V,
- bound: &'v TyParamBound) {
+pub fn walk_ty_param_bound<V: Visitor>(visitor: &mut V, bound: &TyParamBound) {
match *bound {
TraitTyParamBound(ref typ, ref modifier) => {
visitor.visit_poly_trait_ref(typ, modifier);
}
}
-pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
+pub fn walk_generics<V: Visitor>(visitor: &mut V, generics: &Generics) {
for param in &generics.ty_params {
visitor.visit_ident(param.span, param.ident);
walk_list!(visitor, visit_ty_param_bound, ¶m.bounds);
}
}
-pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) {
+pub fn walk_fn_ret_ty<V: Visitor>(visitor: &mut V, ret_ty: &FunctionRetTy) {
if let FunctionRetTy::Ty(ref output_ty) = *ret_ty {
visitor.visit_ty(output_ty)
}
}
-pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
+pub fn walk_fn_decl<V: Visitor>(visitor: &mut V, function_declaration: &FnDecl) {
for argument in &function_declaration.inputs {
visitor.visit_pat(&argument.pat);
visitor.visit_ty(&argument.ty)
walk_fn_ret_ty(visitor, &function_declaration.output)
}
-pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V,
- function_kind: FnKind<'v>) {
+pub fn walk_fn_kind<V: Visitor>(visitor: &mut V, function_kind: FnKind) {
match function_kind {
FnKind::ItemFn(_, generics, _, _, _, _) => {
visitor.visit_generics(generics);
}
}
-pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
- function_kind: FnKind<'v>,
- function_declaration: &'v FnDecl,
- function_body: &'v Block,
- _span: Span) {
- walk_fn_decl(visitor, function_declaration);
- walk_fn_kind(visitor, function_kind);
- visitor.visit_block(function_body)
+pub fn walk_fn<V>(visitor: &mut V, kind: FnKind, declaration: &FnDecl, body: &Block, _span: Span)
+ where V: Visitor,
+{
+ walk_fn_decl(visitor, declaration);
+ walk_fn_kind(visitor, kind);
+ visitor.visit_block(body)
}
-pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
+pub fn walk_trait_item<V: Visitor>(visitor: &mut V, trait_item: &TraitItem) {
visitor.visit_ident(trait_item.span, trait_item.ident);
walk_list!(visitor, visit_attribute, &trait_item.attrs);
match trait_item.node {
walk_list!(visitor, visit_ty_param_bound, bounds);
walk_list!(visitor, visit_ty, default);
}
+ TraitItemKind::Macro(ref mac) => {
+ visitor.visit_mac(mac);
+ }
}
}
-pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
+pub fn walk_impl_item<V: Visitor>(visitor: &mut V, impl_item: &ImplItem) {
visitor.visit_vis(&impl_item.vis);
visitor.visit_ident(impl_item.span, impl_item.ident);
walk_list!(visitor, visit_attribute, &impl_item.attrs);
}
}
-pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,
- struct_definition: &'v VariantData) {
+pub fn walk_struct_def<V: Visitor>(visitor: &mut V, struct_definition: &VariantData) {
walk_list!(visitor, visit_struct_field, struct_definition.fields());
}
-pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
- struct_field: &'v StructField) {
+pub fn walk_struct_field<V: Visitor>(visitor: &mut V, struct_field: &StructField) {
visitor.visit_vis(&struct_field.vis);
walk_opt_ident(visitor, struct_field.span, struct_field.ident);
visitor.visit_ty(&struct_field.ty);
walk_list!(visitor, visit_attribute, &struct_field.attrs);
}
-pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
+pub fn walk_block<V: Visitor>(visitor: &mut V, block: &Block) {
walk_list!(visitor, visit_stmt, &block.stmts);
- walk_list!(visitor, visit_expr, &block.expr);
}
-pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
+pub fn walk_stmt<V: Visitor>(visitor: &mut V, statement: &Stmt) {
match statement.node {
- StmtKind::Decl(ref declaration, _) => visitor.visit_decl(declaration),
- StmtKind::Expr(ref expression, _) | StmtKind::Semi(ref expression, _) => {
+ StmtKind::Local(ref local) => visitor.visit_local(local),
+ StmtKind::Item(ref item) => visitor.visit_item(item),
+ StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => {
visitor.visit_expr(expression)
}
- StmtKind::Mac(ref mac, _, ref attrs) => {
+ StmtKind::Mac(ref mac) => {
+ let (ref mac, _, ref attrs) = **mac;
visitor.visit_mac(mac);
- for attr in attrs.as_attr_slice() {
+ for attr in attrs.iter() {
visitor.visit_attribute(attr);
}
}
}
}
-pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
- match declaration.node {
- DeclKind::Local(ref local) => visitor.visit_local(local),
- DeclKind::Item(ref item) => visitor.visit_item(item),
- }
-}
-
-pub fn walk_mac<'v, V: Visitor<'v>>(_: &mut V, _: &'v Mac) {
+pub fn walk_mac<V: Visitor>(_: &mut V, _: &Mac) {
// Empty!
}
-pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
- for attr in expression.attrs.as_attr_slice() {
+pub fn walk_expr<V: Visitor>(visitor: &mut V, expression: &Expr) {
+ for attr in expression.attrs.iter() {
visitor.visit_attribute(attr);
}
match expression.node {
}
visitor.visit_path(path, expression.id)
}
- ExprKind::Break(ref opt_sp_ident) | ExprKind::Again(ref opt_sp_ident) => {
+ ExprKind::Break(ref opt_sp_ident) | ExprKind::Continue(ref opt_sp_ident) => {
walk_opt_sp_ident(visitor, opt_sp_ident);
}
ExprKind::Ret(ref optional_expression) => {
visitor.visit_expr_post(expression)
}
-pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
+pub fn walk_arm<V: Visitor>(visitor: &mut V, arm: &Arm) {
walk_list!(visitor, visit_pat, &arm.pats);
walk_list!(visitor, visit_expr, &arm.guard);
visitor.visit_expr(&arm.body);
walk_list!(visitor, visit_attribute, &arm.attrs);
}
-pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
+pub fn walk_vis<V: Visitor>(visitor: &mut V, vis: &Visibility) {
if let Visibility::Restricted { ref path, id } = *vis {
visitor.visit_path(path, id);
}
use syntax::ast::{Expr, ItemKind, Generics, MetaItem, VariantData};
use syntax::attr;
-use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
+use syntax_pos::Span;
#[derive(PartialEq)]
enum Mode { Deep, Shallow }
match mode {
Mode::Shallow => {
- cx.expr_block(cx.block(trait_span,
- all_fields.iter()
- .map(subcall)
- .map(|e| cx.stmt_expr(e))
- .collect(),
- Some(cx.expr_deref(trait_span, cx.expr_self(trait_span)))))
+ let mut stmts: Vec<_> =
+ all_fields.iter().map(subcall).map(|e| cx.stmt_expr(e)).collect();
+ stmts.push(cx.stmt_expr(cx.expr_deref(trait_span, cx.expr_self(trait_span))));
+ cx.expr_block(cx.block(trait_span, stmts))
}
Mode::Deep => {
match *vdata {
use deriving::generic::ty::*;
use syntax::ast::{MetaItem, Expr};
-use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
+use syntax_pos::Span;
pub fn expand_deriving_eq(cx: &mut ExtCtxt,
span: Span,
// create `a.<method>(); b.<method>(); c.<method>(); ...`
// (where method is `assert_receiver_is_total_eq`)
let stmts = exprs.into_iter().map(|e| cx.stmt_expr(e)).collect();
- let block = cx.block(span, stmts, None);
+ let block = cx.block(span, stmts);
cx.expr_block(block)
},
Box::new(|cx, sp, _, _| {
use syntax::ast;
use syntax::ast::{MetaItem, Expr};
-use syntax::codemap::{Span, respan, DUMMY_SP};
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::ptr::P;
+use syntax_pos::{Span, DUMMY_SP};
pub fn expand_deriving_debug(cx: &mut ExtCtxt,
span: Span,
let fmt = substr.nonself_args[0].clone();
- let stmts = match *substr.fields {
+ let mut stmts = match *substr.fields {
Struct(_, ref fields) | EnumMatching(_, _, ref fields) => {
let mut stmts = vec![];
if !is_struct {
token::str_to_ident("finish"),
vec![]);
- let block = cx.block(span, stmts, Some(expr));
+ stmts.push(cx.stmt_expr(expr));
+ let block = cx.block(span, stmts);
cx.expr_block(block)
}
init: Some(expr),
id: ast::DUMMY_NODE_ID,
span: sp,
- attrs: None,
+ attrs: ast::ThinVec::new(),
});
- let decl = respan(sp, ast::DeclKind::Local(local));
- respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))
+ ast::Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: ast::StmtKind::Local(local),
+ span: sp,
+ }
}
use deriving::generic::ty::*;
use syntax::ast::{MetaItem, Expr, ExprKind, Mutability};
-use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt,Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::ptr::P;
+use syntax_pos::Span;
pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt,
span: Span,
cx.expr_str(trait_span, substr.type_ident.name.as_str()),
blk
));
- cx.expr_block(cx.block(trait_span, vec!(me), Some(ret)))
+ cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)]))
}
_ => cx.bug("expected Struct or EnumMatching in derive(Encodable)")
use syntax::attr::AttrMetaMethods;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
-use syntax::codemap::{self, respan, DUMMY_SP};
-use syntax::codemap::Span;
-use syntax::errors::Handler;
+use syntax::codemap::{self, respan};
use syntax::util::move_map::MoveMap;
use syntax::parse::token::{keywords, InternedString};
use syntax::ptr::P;
+use syntax_pos::{Span, DUMMY_SP};
+use errors::Handler;
use self::ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty};
types: Vec<P<ast::Ty>>,
}
- impl<'a> visit::Visitor<'a> for Visitor<'a> {
- fn visit_ty(&mut self, ty: &'a ast::Ty) {
+ impl<'a> visit::Visitor for Visitor<'a> {
+ fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node {
ast::TyKind::Path(_, ref path) if !path.global => {
match path.segments.first() {
// }
let all_match = cx.expr_match(sp, match_arg, match_arms);
let arm_expr = cx.expr_if(sp, discriminant_test, all_match, Some(arm_expr));
- cx.expr_block(
- cx.block_all(sp, index_let_stmts, Some(arm_expr)))
+ index_let_stmts.push(cx.stmt_expr(arm_expr));
+ cx.expr_block(cx.block(sp, index_let_stmts))
} else if variants.is_empty() {
// As an additional wrinkle, For a zero-variant enum A,
// currently the compiler
use deriving::generic::ty::*;
use syntax::ast::{MetaItem, Expr, Mutability};
-use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
+use syntax_pos::Span;
pub fn expand_deriving_hash(cx: &mut ExtCtxt,
span: Span,
stmts.push(call_hash(span, self_.clone()));
}
- cx.expr_block(cx.block(trait_span, stmts, None))
+ cx.expr_block(cx.block(trait_span, stmts))
}
use syntax::ext::base::{MultiDecorator, MultiItemDecorator, MultiModifier};
use syntax::ext::build::AstBuilder;
use syntax::feature_gate;
-use syntax::codemap::{self, Span};
+use syntax::codemap;
use syntax::parse::token::{intern, intern_and_get_ident};
use syntax::ptr::P;
+use syntax_pos::Span;
macro_rules! pathvec {
($($x:ident)::+) => (
let call = cx.expr_call_global(span, path, args);
cx.expr_block(P(ast::Block {
- stmts: vec![],
- expr: Some(call),
+ stmts: vec![cx.stmt_expr(call)],
id: ast::DUMMY_NODE_ID,
rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
span: span }))
use fmt_macros as parse;
use syntax::ast;
-use syntax::codemap::{Span, respan, DUMMY_SP};
use syntax::ext::base::*;
use syntax::ext::base;
use syntax::ext::build::AstBuilder;
use syntax::fold::Folder;
use syntax::parse::token::{self, keywords};
use syntax::ptr::P;
+use syntax_pos::{Span, DUMMY_SP};
+use syntax::tokenstream;
use std::collections::HashMap;
/// Some((fmtstr, unnamed arguments, ordering of named arguments,
/// named arguments))
/// ```
-fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
+fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-> Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<String>,
HashMap<String, P<ast::Expr>>)> {
let mut args = Vec::new();
let name = ecx.ident_of(name);
let item = ecx.item(sp, name, vec![], st);
- let decl = respan(sp, ast::DeclKind::Item(item));
+ let stmt = ast::Stmt {
+ id: ast::DUMMY_NODE_ID,
+ node: ast::StmtKind::Item(item),
+ span: sp,
+ };
// Wrap the declaration in a block so that it forms a single expression.
- ecx.expr_block(ecx.block(sp, vec![stmt], Some(ecx.expr_ident(sp, name))))
- ecx.expr_block(ecx.block(sp, vec![
- respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID)),
- ecx.stmt_expr(ecx.expr_ident(sp, name)),
- ]))
++ ecx.expr_block(ecx.block(sp, vec![stmt, ecx.stmt_expr(ecx.expr_ident(sp, name))]))
}
/// Actually builds the expression which the iformat! block will be expanded
}
pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, sp: Span,
- tts: &[ast::TokenTree])
+ tts: &[tokenstream::TokenTree])
-> Box<base::MacResult+'cx> {
match parse_args(ecx, sp, tts) {