Rollup merge of #34316 - jseyfried:refactor_ast_stmt, r=eddyb
Refactor away `ast::Decl`, refactor `ast::Stmt`, and rename `ast::ExprKind::Again` to `ast::ExprKind::Continue`.
This commit is contained in:
commit
8748cd92d0
@ -238,19 +238,6 @@ impl<'a> LoweringContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
|
||||||
hir::TypeBinding {
|
hir::TypeBinding {
|
||||||
id: b.id,
|
id: b.id,
|
||||||
@ -1225,7 +1212,7 @@ impl<'a> LoweringContext<'a> {
|
|||||||
hir::ExprPath(hir_qself, self.lower_path(path))
|
hir::ExprPath(hir_qself, self.lower_path(path))
|
||||||
}
|
}
|
||||||
ExprKind::Break(opt_ident) => hir::ExprBreak(self.lower_opt_sp_ident(opt_ident)),
|
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::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| self.lower_expr(x))),
|
||||||
ExprKind::InlineAsm(InlineAsm {
|
ExprKind::InlineAsm(InlineAsm {
|
||||||
ref inputs,
|
ref inputs,
|
||||||
@ -1581,21 +1568,29 @@ impl<'a> LoweringContext<'a> {
|
|||||||
|
|
||||||
fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
|
fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
|
||||||
match s.node {
|
match s.node {
|
||||||
StmtKind::Decl(ref d, id) => {
|
StmtKind::Local(ref l) => Spanned {
|
||||||
|
node: hir::StmtDecl(P(Spanned {
|
||||||
|
node: hir::DeclLocal(self.lower_local(l)),
|
||||||
|
span: s.span,
|
||||||
|
}), 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 {
|
Spanned {
|
||||||
node: hir::StmtDecl(self.lower_decl(d), id),
|
node: hir::StmtExpr(self.lower_expr(e), s.id),
|
||||||
span: s.span,
|
span: s.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StmtKind::Expr(ref e, id) => {
|
StmtKind::Semi(ref e) => {
|
||||||
Spanned {
|
Spanned {
|
||||||
node: hir::StmtExpr(self.lower_expr(e), id),
|
node: hir::StmtSemi(self.lower_expr(e), s.id),
|
||||||
span: s.span,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StmtKind::Semi(ref e, id) => {
|
|
||||||
Spanned {
|
|
||||||
node: hir::StmtSemi(self.lower_expr(e), id),
|
|
||||||
span: s.span,
|
span: s.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1005,11 +1005,6 @@ impl<'a> ast_visit::Visitor for EarlyContext<'a> {
|
|||||||
ast_visit::walk_arm(self, a);
|
ast_visit::walk_arm(self, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_decl(&mut self, d: &ast::Decl) {
|
|
||||||
run_lints!(self, check_decl, early_passes, d);
|
|
||||||
ast_visit::walk_decl(self, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_expr_post(&mut self, e: &ast::Expr) {
|
fn visit_expr_post(&mut self, e: &ast::Expr) {
|
||||||
run_lints!(self, check_expr_post, early_passes, e);
|
run_lints!(self, check_expr_post, early_passes, e);
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,6 @@ pub trait EarlyLintPass: LintPass {
|
|||||||
fn check_stmt(&mut self, _: &EarlyContext, _: &ast::Stmt) { }
|
fn check_stmt(&mut self, _: &EarlyContext, _: &ast::Stmt) { }
|
||||||
fn check_arm(&mut self, _: &EarlyContext, _: &ast::Arm) { }
|
fn check_arm(&mut self, _: &EarlyContext, _: &ast::Arm) { }
|
||||||
fn check_pat(&mut self, _: &EarlyContext, _: &ast::Pat) { }
|
fn check_pat(&mut self, _: &EarlyContext, _: &ast::Pat) { }
|
||||||
fn check_decl(&mut self, _: &EarlyContext, _: &ast::Decl) { }
|
|
||||||
fn check_expr(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
fn check_expr(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
||||||
fn check_expr_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
fn check_expr_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
||||||
fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
|
fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
|
||||||
|
@ -365,12 +365,9 @@ impl EarlyLintPass for UnusedParens {
|
|||||||
|
|
||||||
fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) {
|
fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) {
|
||||||
let (value, msg) = match s.node {
|
let (value, msg) = match s.node {
|
||||||
ast::StmtKind::Decl(ref decl, _) => match decl.node {
|
ast::StmtKind::Local(ref local) => match local.init {
|
||||||
ast::DeclKind::Local(ref local) => match local.init {
|
Some(ref value) => (value, "assigned value"),
|
||||||
Some(ref value) => (value, "assigned value"),
|
None => return
|
||||||
None => return
|
|
||||||
},
|
|
||||||
_ => return
|
|
||||||
},
|
},
|
||||||
_ => return
|
_ => return
|
||||||
};
|
};
|
||||||
|
@ -73,7 +73,7 @@ impl<'a> Visitor for AstValidator<'a> {
|
|||||||
match expr.node {
|
match expr.node {
|
||||||
ExprKind::While(_, _, Some(ident)) | ExprKind::Loop(_, Some(ident)) |
|
ExprKind::While(_, _, Some(ident)) | ExprKind::Loop(_, Some(ident)) |
|
||||||
ExprKind::WhileLet(_, _, _, Some(ident)) | ExprKind::ForLoop(_, _, _, Some(ident)) |
|
ExprKind::WhileLet(_, _, _, Some(ident)) | ExprKind::ForLoop(_, _, _, Some(ident)) |
|
||||||
ExprKind::Break(Some(ident)) | ExprKind::Again(Some(ident)) => {
|
ExprKind::Break(Some(ident)) | ExprKind::Continue(Some(ident)) => {
|
||||||
self.check_label(ident.node, ident.span, expr.id);
|
self.check_label(ident.node, ident.span, expr.id);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -30,10 +30,10 @@ use syntax::ast::Name;
|
|||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
|
||||||
use syntax::ast::{Block, Crate, DeclKind};
|
use syntax::ast::{Block, Crate};
|
||||||
use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind};
|
use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind};
|
||||||
use syntax::ast::{Mutability, PathListItemKind};
|
use syntax::ast::{Mutability, PathListItemKind};
|
||||||
use syntax::ast::{Stmt, StmtKind, TraitItemKind};
|
use syntax::ast::{StmtKind, TraitItemKind};
|
||||||
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
|
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||||
use syntax::visit::{self, Visitor};
|
use syntax::visit::{self, Visitor};
|
||||||
|
|
||||||
@ -85,17 +85,11 @@ impl<'b> Resolver<'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
|
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
|
||||||
fn is_item(statement: &Stmt) -> bool {
|
|
||||||
if let StmtKind::Decl(ref declaration, _) = statement.node {
|
|
||||||
if let DeclKind::Item(_) = declaration.node {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
// If any statements are items, we need to create an anonymous module
|
// If any statements are items, we need to create an anonymous module
|
||||||
block.stmts.iter().any(is_item)
|
block.stmts.iter().any(|statement| match statement.node {
|
||||||
|
StmtKind::Item(_) => true,
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs the reduced graph for one item.
|
/// Constructs the reduced graph for one item.
|
||||||
|
@ -2951,7 +2951,7 @@ impl<'a> Resolver<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprKind::Break(Some(label)) | ExprKind::Again(Some(label)) => {
|
ExprKind::Break(Some(label)) | ExprKind::Continue(Some(label)) => {
|
||||||
match self.search_label(mtwt::resolve(label.node)) {
|
match self.search_label(mtwt::resolve(label.node)) {
|
||||||
None => {
|
None => {
|
||||||
self.record_def(expr.id, err_path_resolution());
|
self.record_def(expr.id, err_path_resolution());
|
||||||
|
@ -1423,8 +1423,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_stmt(&mut self, s: &ast::Stmt) {
|
fn visit_stmt(&mut self, s: &ast::Stmt) {
|
||||||
let id = s.node.id();
|
self.process_macro_use(s.span, s.id);
|
||||||
self.process_macro_use(s.span, id.unwrap());
|
|
||||||
visit::walk_stmt(self, s)
|
visit::walk_stmt(self, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ use tokenstream::{TokenTree};
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||||
|
|
||||||
@ -811,41 +810,35 @@ impl UnOp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A statement
|
/// 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 {
|
impl fmt::Debug for Stmt {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "stmt({}: {})",
|
write!(f, "stmt({}: {})", self.id.to_string(), pprust::stmt_to_string(self))
|
||||||
self.node.id()
|
|
||||||
.map_or(Cow::Borrowed("<macro>"),|id|Cow::Owned(id.to_string())),
|
|
||||||
pprust::stmt_to_string(self))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
|
||||||
pub enum StmtKind {
|
pub enum StmtKind {
|
||||||
/// Could be an item or a local (let) binding:
|
/// A local (let) binding.
|
||||||
Decl(P<Decl>, NodeId),
|
Local(P<Local>),
|
||||||
|
|
||||||
/// Expr without trailing semi-colon (must have unit type):
|
/// An item definition.
|
||||||
Expr(P<Expr>, NodeId),
|
Item(P<Item>),
|
||||||
|
|
||||||
/// Expr with trailing semi-colon (may have any type):
|
/// Expr without trailing semi-colon (must have unit type).
|
||||||
Semi(P<Expr>, NodeId),
|
Expr(P<Expr>),
|
||||||
|
|
||||||
Mac(P<Mac>, MacStmtStyle, ThinAttributes),
|
/// Expr with trailing semi-colon (may have any type).
|
||||||
}
|
Semi(P<Expr>),
|
||||||
|
|
||||||
impl StmtKind {
|
Mac(P<(Mac, MacStmtStyle, ThinAttributes)>),
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
@ -875,16 +868,6 @@ pub struct Local {
|
|||||||
pub attrs: ThinAttributes,
|
pub attrs: ThinAttributes,
|
||||||
}
|
}
|
||||||
|
|
||||||
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>),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An arm of a 'match'.
|
/// An arm of a 'match'.
|
||||||
///
|
///
|
||||||
/// E.g. `0...10 => { println!("match!") }` as in
|
/// E.g. `0...10 => { println!("match!") }` as in
|
||||||
@ -1053,7 +1036,7 @@ pub enum ExprKind {
|
|||||||
/// A `break`, with an optional label to break
|
/// A `break`, with an optional label to break
|
||||||
Break(Option<SpannedIdent>),
|
Break(Option<SpannedIdent>),
|
||||||
/// A `continue`, with an optional label
|
/// A `continue`, with an optional label
|
||||||
Again(Option<SpannedIdent>),
|
Continue(Option<SpannedIdent>),
|
||||||
/// A `return`, with an optional value to be returned
|
/// A `return`, with an optional value to be returned
|
||||||
Ret(Option<P<Expr>>),
|
Ret(Option<P<Expr>>),
|
||||||
|
|
||||||
|
@ -16,8 +16,7 @@ pub use self::IntType::*;
|
|||||||
|
|
||||||
use ast;
|
use ast;
|
||||||
use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaItemKind};
|
use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaItemKind};
|
||||||
use ast::{Stmt, StmtKind, DeclKind};
|
use ast::{Expr, Item, Local, Stmt, StmtKind};
|
||||||
use ast::{Expr, Item, Local, Decl};
|
|
||||||
use codemap::{spanned, dummy_spanned, Spanned};
|
use codemap::{spanned, dummy_spanned, Spanned};
|
||||||
use syntax_pos::{Span, BytePos};
|
use syntax_pos::{Span, BytePos};
|
||||||
use errors::Handler;
|
use errors::Handler;
|
||||||
@ -909,38 +908,28 @@ impl<T: HasAttrs + 'static> HasAttrs for P<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasAttrs for DeclKind {
|
|
||||||
fn attrs(&self) -> &[Attribute] {
|
|
||||||
match *self {
|
|
||||||
DeclKind::Local(ref local) => local.attrs(),
|
|
||||||
DeclKind::Item(ref item) => item.attrs(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
|
|
||||||
match self {
|
|
||||||
DeclKind::Local(local) => DeclKind::Local(local.map_attrs(f)),
|
|
||||||
DeclKind::Item(item) => DeclKind::Item(item.map_attrs(f)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasAttrs for StmtKind {
|
impl HasAttrs for StmtKind {
|
||||||
fn attrs(&self) -> &[Attribute] {
|
fn attrs(&self) -> &[Attribute] {
|
||||||
match *self {
|
match *self {
|
||||||
StmtKind::Decl(ref decl, _) => decl.attrs(),
|
StmtKind::Local(ref local) => local.attrs(),
|
||||||
StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => expr.attrs(),
|
StmtKind::Item(ref item) => item.attrs(),
|
||||||
StmtKind::Mac(_, _, ref attrs) => attrs.attrs(),
|
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(),
|
||||||
|
StmtKind::Mac(ref mac) => {
|
||||||
|
let (_, _, ref attrs) = **mac;
|
||||||
|
attrs.attrs()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
|
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
|
||||||
match self {
|
match self {
|
||||||
StmtKind::Decl(decl, id) => StmtKind::Decl(decl.map_attrs(f), id),
|
StmtKind::Local(local) => StmtKind::Local(local.map_attrs(f)),
|
||||||
StmtKind::Expr(expr, id) => StmtKind::Expr(expr.map_attrs(f), id),
|
StmtKind::Item(item) => StmtKind::Item(item.map_attrs(f)),
|
||||||
StmtKind::Semi(expr, id) => StmtKind::Semi(expr.map_attrs(f), id),
|
StmtKind::Expr(expr) => StmtKind::Expr(expr.map_attrs(f)),
|
||||||
StmtKind::Mac(mac, style, attrs) =>
|
StmtKind::Semi(expr) => StmtKind::Semi(expr.map_attrs(f)),
|
||||||
StmtKind::Mac(mac, style, attrs.map_attrs(f)),
|
StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, style, attrs)| {
|
||||||
|
(mac, style, attrs.map_attrs(f))
|
||||||
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -967,4 +956,4 @@ derive_has_attrs_from_field! {
|
|||||||
Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm
|
Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm
|
||||||
}
|
}
|
||||||
|
|
||||||
derive_has_attrs_from_field! { Decl: .node, Stmt: .node, ast::Variant: .node.attrs }
|
derive_has_attrs_from_field! { Stmt: .node, ast::Variant: .node.attrs }
|
||||||
|
@ -213,17 +213,10 @@ impl<'a> fold::Folder for StripUnconfigured<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
|
fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
|
||||||
let is_item = match stmt.node {
|
|
||||||
ast::StmtKind::Decl(ref decl, _) => match decl.node {
|
|
||||||
ast::DeclKind::Item(_) => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// avoid calling `visit_stmt_or_expr_attrs` on items
|
// avoid calling `visit_stmt_or_expr_attrs` on items
|
||||||
if !is_item {
|
match stmt.node {
|
||||||
self.visit_stmt_or_expr_attrs(stmt.attrs());
|
ast::StmtKind::Item(_) => {}
|
||||||
|
_ => self.visit_stmt_or_expr_attrs(stmt.attrs()),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.configure(stmt).map(|stmt| fold::noop_fold_stmt(stmt, self))
|
self.configure(stmt).map(|stmt| fold::noop_fold_stmt(stmt, self))
|
||||||
|
@ -221,10 +221,11 @@ impl<F> IdentMacroExpander for F
|
|||||||
// Use a macro because forwarding to a simple function has type system issues
|
// Use a macro because forwarding to a simple function has type system issues
|
||||||
macro_rules! make_stmts_default {
|
macro_rules! make_stmts_default {
|
||||||
($me:expr) => {
|
($me:expr) => {
|
||||||
$me.make_expr().map(|e| {
|
$me.make_expr().map(|e| SmallVector::one(ast::Stmt {
|
||||||
SmallVector::one(codemap::respan(
|
id: ast::DUMMY_NODE_ID,
|
||||||
e.span, ast::StmtKind::Expr(e, ast::DUMMY_NODE_ID)))
|
span: e.span,
|
||||||
})
|
node: ast::StmtKind::Expr(e),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,10 +437,11 @@ impl MacResult for DummyResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> {
|
fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> {
|
||||||
Some(SmallVector::one(
|
Some(SmallVector::one(ast::Stmt {
|
||||||
codemap::respan(self.span,
|
id: ast::DUMMY_NODE_ID,
|
||||||
ast::StmtKind::Expr(DummyResult::raw_expr(self.span),
|
node: ast::StmtKind::Expr(DummyResult::raw_expr(self.span)),
|
||||||
ast::DUMMY_NODE_ID))))
|
span: self.span,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +509,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt {
|
fn stmt_expr(&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,
|
fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident,
|
||||||
@ -528,8 +532,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||||||
span: sp,
|
span: sp,
|
||||||
attrs: None,
|
attrs: None,
|
||||||
});
|
});
|
||||||
let decl = respan(sp, ast::DeclKind::Local(local));
|
ast::Stmt {
|
||||||
respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
node: ast::StmtKind::Local(local),
|
||||||
|
span: sp,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stmt_let_typed(&self,
|
fn stmt_let_typed(&self,
|
||||||
@ -553,8 +560,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||||||
span: sp,
|
span: sp,
|
||||||
attrs: None,
|
attrs: None,
|
||||||
});
|
});
|
||||||
let decl = respan(sp, ast::DeclKind::Local(local));
|
P(ast::Stmt {
|
||||||
P(respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID)))
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
node: ast::StmtKind::Local(local),
|
||||||
|
span: sp,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block(&self, span: Span, stmts: Vec<ast::Stmt>,
|
fn block(&self, span: Span, stmts: Vec<ast::Stmt>,
|
||||||
@ -563,8 +573,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt {
|
fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt {
|
||||||
let decl = respan(sp, ast::DeclKind::Item(item));
|
ast::Stmt {
|
||||||
respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
node: ast::StmtKind::Item(item),
|
||||||
|
span: sp,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
|
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// 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::{Local, Ident, Mac_, Name, SpannedIdent};
|
||||||
use ast::{MacStmtStyle, Mrk, Stmt, StmtKind, ItemKind};
|
use ast::{MacStmtStyle, Mrk, Stmt, StmtKind, ItemKind};
|
||||||
use ast;
|
use ast;
|
||||||
@ -439,25 +439,25 @@ fn expand_stmt(stmt: Stmt, fld: &mut MacroExpander) -> SmallVector<Stmt> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (mac, style, attrs) = match stmt.node {
|
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)
|
_ => return expand_non_macro_stmt(stmt, fld)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut fully_expanded: SmallVector<ast::Stmt> =
|
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_attr_vec(), stmt.span, fld);
|
||||||
|
|
||||||
// If this is a macro invocation with a semicolon, then apply that
|
// If this is a macro invocation with a semicolon, then apply that
|
||||||
// semicolon to the final statement produced by expansion.
|
// semicolon to the final statement produced by expansion.
|
||||||
if style == MacStmtStyle::Semicolon {
|
if style == MacStmtStyle::Semicolon {
|
||||||
if let Some(stmt) = fully_expanded.pop() {
|
if let Some(stmt) = fully_expanded.pop() {
|
||||||
let new_stmt = Spanned {
|
fully_expanded.push(Stmt {
|
||||||
|
id: stmt.id,
|
||||||
node: match stmt.node {
|
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 */
|
_ => stmt.node /* might already have a semi */
|
||||||
},
|
},
|
||||||
span: stmt.span
|
span: stmt.span,
|
||||||
};
|
});
|
||||||
fully_expanded.push(new_stmt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,73 +466,53 @@ fn expand_stmt(stmt: Stmt, fld: &mut MacroExpander) -> SmallVector<Stmt> {
|
|||||||
|
|
||||||
// expand a non-macro stmt. this is essentially the fallthrough for
|
// expand a non-macro stmt. this is essentially the fallthrough for
|
||||||
// expand_stmt, above.
|
// 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> {
|
-> SmallVector<Stmt> {
|
||||||
// is it a let?
|
// is it a let?
|
||||||
match node {
|
match stmt.node {
|
||||||
StmtKind::Decl(decl, node_id) => decl.and_then(|Spanned {node: decl, span}| match decl {
|
StmtKind::Local(local) => {
|
||||||
DeclKind::Local(local) => {
|
// take it apart:
|
||||||
// take it apart:
|
let rewritten_local = local.map(|Local {id, pat, ty, init, span, attrs}| {
|
||||||
let rewritten_local = local.map(|Local {id, pat, ty, init, span, attrs}| {
|
// expand the ty since TyKind::FixedLengthVec contains an Expr
|
||||||
// expand the ty since TyKind::FixedLengthVec contains an Expr
|
// and thus may have a macro use
|
||||||
// and thus may have a macro use
|
let expanded_ty = ty.map(|t| fld.fold_ty(t));
|
||||||
let expanded_ty = ty.map(|t| fld.fold_ty(t));
|
// expand the pat (it might contain macro uses):
|
||||||
// expand the pat (it might contain macro uses):
|
let expanded_pat = fld.fold_pat(pat);
|
||||||
let expanded_pat = fld.fold_pat(pat);
|
// find the PatIdents in the pattern:
|
||||||
// find the PatIdents in the pattern:
|
// oh dear heaven... this is going to include the enum
|
||||||
// oh dear heaven... this is going to include the enum
|
// names, as well... but that should be okay, as long as
|
||||||
// names, as well... but that should be okay, as long as
|
// the new names are gensyms for the old ones.
|
||||||
// the new names are gensyms for the old ones.
|
// generate fresh names, push them to a new pending list
|
||||||
// generate fresh names, push them to a new pending list
|
let idents = pattern_bindings(&expanded_pat);
|
||||||
let idents = pattern_bindings(&expanded_pat);
|
let mut new_pending_renames =
|
||||||
let mut new_pending_renames =
|
idents.iter().map(|ident| (*ident, fresh_name(*ident))).collect();
|
||||||
idents.iter().map(|ident| (*ident, fresh_name(*ident))).collect();
|
// rewrite the pattern using the new names (the old
|
||||||
// rewrite the pattern using the new names (the old
|
// ones have already been applied):
|
||||||
// ones have already been applied):
|
let rewritten_pat = {
|
||||||
let rewritten_pat = {
|
// nested binding to allow borrow to expire:
|
||||||
// nested binding to allow borrow to expire:
|
let mut rename_fld = IdentRenamer{renames: &mut new_pending_renames};
|
||||||
let mut rename_fld = IdentRenamer{renames: &mut new_pending_renames};
|
rename_fld.fold_pat(expanded_pat)
|
||||||
rename_fld.fold_pat(expanded_pat)
|
};
|
||||||
};
|
// add them to the existing pending renames:
|
||||||
// add them to the existing pending renames:
|
fld.cx.syntax_env.info().pending_renames
|
||||||
fld.cx.syntax_env.info().pending_renames
|
.extend(new_pending_renames);
|
||||||
.extend(new_pending_renames);
|
Local {
|
||||||
Local {
|
id: id,
|
||||||
id: id,
|
ty: expanded_ty,
|
||||||
ty: expanded_ty,
|
pat: rewritten_pat,
|
||||||
pat: rewritten_pat,
|
// also, don't forget to expand the init:
|
||||||
// also, don't forget to expand the init:
|
init: init.map(|e| fld.fold_expr(e)),
|
||||||
init: init.map(|e| fld.fold_expr(e)),
|
span: span,
|
||||||
span: span,
|
attrs: fold::fold_thin_attrs(attrs, fld),
|
||||||
attrs: fold::fold_thin_attrs(attrs, fld),
|
}
|
||||||
}
|
});
|
||||||
});
|
SmallVector::one(Stmt {
|
||||||
SmallVector::one(Spanned {
|
id: stmt.id,
|
||||||
node: StmtKind::Decl(P(Spanned {
|
node: StmtKind::Local(rewritten_local),
|
||||||
node: DeclKind::Local(rewritten_local),
|
span: stmt.span,
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
_ => noop_fold_stmt(stmt, fld),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,10 +102,6 @@ pub trait Folder : Sized {
|
|||||||
noop_fold_pat(p, self)
|
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> {
|
fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
|
||||||
e.map(|e| noop_fold_expr(e, self))
|
e.map(|e| noop_fold_expr(e, self))
|
||||||
}
|
}
|
||||||
@ -349,19 +345,6 @@ pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm, fld: &mut T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
pub fn noop_fold_ty_binding<T: Folder>(b: TypeBinding, fld: &mut T) -> TypeBinding {
|
||||||
TypeBinding {
|
TypeBinding {
|
||||||
id: fld.new_id(b.id),
|
id: fld.new_id(b.id),
|
||||||
@ -1248,7 +1231,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
|
|||||||
respan(folder.new_span(label.span),
|
respan(folder.new_span(label.span),
|
||||||
folder.fold_ident(label.node)))
|
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),
|
respan(folder.new_span(label.span),
|
||||||
folder.fold_ident(label.node)))
|
folder.fold_ident(label.node)))
|
||||||
),
|
),
|
||||||
@ -1305,44 +1288,52 @@ pub fn noop_fold_exprs<T: Folder>(es: Vec<P<Expr>>, folder: &mut T) -> Vec<P<Exp
|
|||||||
es.move_flat_map(|e| folder.fold_opt_expr(e))
|
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> {
|
-> SmallVector<Stmt> {
|
||||||
|
let id = folder.new_id(id);
|
||||||
let span = folder.new_span(span);
|
let span = folder.new_span(span);
|
||||||
|
|
||||||
match node {
|
match node {
|
||||||
StmtKind::Decl(d, id) => {
|
StmtKind::Local(local) => SmallVector::one(Stmt {
|
||||||
let id = folder.new_id(id);
|
id: id,
|
||||||
folder.fold_decl(d).into_iter().map(|d| Spanned {
|
node: StmtKind::Local(folder.fold_local(local)),
|
||||||
node: StmtKind::Decl(d, id),
|
span: span,
|
||||||
span: span
|
}),
|
||||||
}).collect()
|
StmtKind::Item(item) => folder.fold_item(item).into_iter().map(|item| Stmt {
|
||||||
}
|
id: id,
|
||||||
StmtKind::Expr(e, id) => {
|
node: StmtKind::Item(item),
|
||||||
let id = folder.new_id(id);
|
span: span,
|
||||||
if let Some(e) = folder.fold_opt_expr(e) {
|
}).collect(),
|
||||||
SmallVector::one(Spanned {
|
StmtKind::Expr(expr) => {
|
||||||
node: StmtKind::Expr(e, id),
|
if let Some(expr) = folder.fold_opt_expr(expr) {
|
||||||
span: span
|
SmallVector::one(Stmt {
|
||||||
|
id: id,
|
||||||
|
node: StmtKind::Expr(expr),
|
||||||
|
span: span,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
SmallVector::zero()
|
SmallVector::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StmtKind::Semi(e, id) => {
|
StmtKind::Semi(expr) => {
|
||||||
let id = folder.new_id(id);
|
if let Some(expr) = folder.fold_opt_expr(expr) {
|
||||||
if let Some(e) = folder.fold_opt_expr(e) {
|
SmallVector::one(Stmt {
|
||||||
SmallVector::one(Spanned {
|
id: id,
|
||||||
node: StmtKind::Semi(e, id),
|
node: StmtKind::Semi(expr),
|
||||||
span: span
|
span: span,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
SmallVector::zero()
|
SmallVector::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StmtKind::Mac(mac, semi, attrs) => SmallVector::one(Spanned {
|
StmtKind::Mac(mac) => SmallVector::one(Stmt {
|
||||||
node: StmtKind::Mac(mac.map(|m| folder.fold_mac(m)),
|
id: id,
|
||||||
semi,
|
node: StmtKind::Mac(mac.map(|(mac, semi, attrs)| {
|
||||||
attrs.map_thin_attrs(|v| fold_attrs(v, folder))),
|
let mac = folder.fold_mac(mac);
|
||||||
span: span
|
let attrs = attrs.map_thin_attrs(|attrs| fold_attrs(attrs, folder));
|
||||||
|
(mac, semi, attrs)
|
||||||
|
})),
|
||||||
|
span: span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,13 +47,9 @@ pub fn expr_is_simple_block(e: &ast::Expr) -> bool {
|
|||||||
/// seen the semicolon, and thus don't need another.
|
/// seen the semicolon, and thus don't need another.
|
||||||
pub fn stmt_ends_with_semi(stmt: &ast::StmtKind) -> bool {
|
pub fn stmt_ends_with_semi(stmt: &ast::StmtKind) -> bool {
|
||||||
match *stmt {
|
match *stmt {
|
||||||
ast::StmtKind::Decl(ref d, _) => {
|
ast::StmtKind::Local(_) => true,
|
||||||
match d.node {
|
ast::StmtKind::Item(_) => false,
|
||||||
ast::DeclKind::Local(_) => true,
|
ast::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(e),
|
||||||
ast::DeclKind::Item(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::StmtKind::Expr(ref e, _) => expr_requires_semi_to_be_stmt(e),
|
|
||||||
ast::StmtKind::Semi(..) => false,
|
ast::StmtKind::Semi(..) => false,
|
||||||
ast::StmtKind::Mac(..) => false,
|
ast::StmtKind::Mac(..) => false,
|
||||||
}
|
}
|
||||||
|
@ -844,7 +844,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test] fn parse_stmt_1 () {
|
#[test] fn parse_stmt_1 () {
|
||||||
assert!(string_to_stmt("b;".to_string()) ==
|
assert!(string_to_stmt("b;".to_string()) ==
|
||||||
Some(Spanned{
|
Some(ast::Stmt {
|
||||||
node: ast::StmtKind::Expr(P(ast::Expr {
|
node: ast::StmtKind::Expr(P(ast::Expr {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprKind::Path(None, ast::Path {
|
node: ast::ExprKind::Path(None, ast::Path {
|
||||||
@ -858,8 +858,8 @@ mod tests {
|
|||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
span: sp(0,1),
|
span: sp(0,1),
|
||||||
attrs: None}),
|
attrs: None})),
|
||||||
ast::DUMMY_NODE_ID),
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: sp(0,1)}))
|
span: sp(0,1)}))
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -935,7 +935,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
P(ast::Block {
|
P(ast::Block {
|
||||||
stmts: vec!(Spanned{
|
stmts: vec!(ast::Stmt {
|
||||||
node: ast::StmtKind::Semi(P(ast::Expr{
|
node: ast::StmtKind::Semi(P(ast::Expr{
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprKind::Path(None,
|
node: ast::ExprKind::Path(None,
|
||||||
@ -953,8 +953,8 @@ mod tests {
|
|||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
span: sp(17,18),
|
span: sp(17,18),
|
||||||
attrs: None,}),
|
attrs: None,})),
|
||||||
ast::DUMMY_NODE_ID),
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: sp(17,19)}),
|
span: sp(17,19)}),
|
||||||
expr: None,
|
expr: None,
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -16,7 +16,7 @@ use ast::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind};
|
|||||||
use ast::Block;
|
use ast::Block;
|
||||||
use ast::{BlockCheckMode, CaptureBy};
|
use ast::{BlockCheckMode, CaptureBy};
|
||||||
use ast::{Constness, Crate, CrateConfig};
|
use ast::{Constness, Crate, CrateConfig};
|
||||||
use ast::{Decl, DeclKind, Defaultness};
|
use ast::Defaultness;
|
||||||
use ast::EnumDef;
|
use ast::EnumDef;
|
||||||
use ast::{Expr, ExprKind, RangeLimits};
|
use ast::{Expr, ExprKind, RangeLimits};
|
||||||
use ast::{Field, FnDecl};
|
use ast::{Field, FnDecl};
|
||||||
@ -2312,14 +2312,14 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Continue) {
|
if self.eat_keyword(keywords::Continue) {
|
||||||
let ex = if self.token.is_lifetime() {
|
let ex = if self.token.is_lifetime() {
|
||||||
let ex = ExprKind::Again(Some(Spanned{
|
let ex = ExprKind::Continue(Some(Spanned{
|
||||||
node: self.get_lifetime(),
|
node: self.get_lifetime(),
|
||||||
span: self.span
|
span: self.span
|
||||||
}));
|
}));
|
||||||
self.bump();
|
self.bump();
|
||||||
ex
|
ex
|
||||||
} else {
|
} else {
|
||||||
ExprKind::Again(None)
|
ExprKind::Continue(None)
|
||||||
};
|
};
|
||||||
let hi = self.last_span.hi;
|
let hi = self.last_span.hi;
|
||||||
return Ok(self.mk_expr(lo, hi, ex, attrs));
|
return Ok(self.mk_expr(lo, hi, ex, attrs));
|
||||||
@ -3826,13 +3826,6 @@ impl<'a> Parser<'a> {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
/// Parse a structure field
|
||||||
fn parse_name_and_ty(&mut self, pr: Visibility,
|
fn parse_name_and_ty(&mut self, pr: Visibility,
|
||||||
attrs: Vec<Attribute> ) -> PResult<'a, StructField> {
|
attrs: Vec<Attribute> ) -> PResult<'a, StructField> {
|
||||||
@ -3945,12 +3938,12 @@ impl<'a> Parser<'a> {
|
|||||||
let attrs = self.parse_outer_attributes()?;
|
let attrs = self.parse_outer_attributes()?;
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
|
|
||||||
Ok(Some(if self.check_keyword(keywords::Let) {
|
Ok(Some(if self.eat_keyword(keywords::Let) {
|
||||||
self.expect_keyword(keywords::Let)?;
|
Stmt {
|
||||||
let decl = self.parse_let(attrs.into_thin_attrs())?;
|
id: ast::DUMMY_NODE_ID,
|
||||||
let hi = decl.span.hi;
|
node: StmtKind::Local(self.parse_local(attrs.into_thin_attrs())?),
|
||||||
let stmt = StmtKind::Decl(decl, ast::DUMMY_NODE_ID);
|
span: mk_sp(lo, self.last_span.hi),
|
||||||
spanned(lo, hi, stmt)
|
}
|
||||||
} else if self.token.is_ident()
|
} else if self.token.is_ident()
|
||||||
&& !self.token.is_any_keyword()
|
&& !self.token.is_any_keyword()
|
||||||
&& self.look_ahead(1, |t| *t == token::Not) {
|
&& self.look_ahead(1, |t| *t == token::Not) {
|
||||||
@ -4001,9 +3994,12 @@ impl<'a> Parser<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if id.name == keywords::Invalid.name() {
|
if id.name == keywords::Invalid.name() {
|
||||||
let mac = P(spanned(lo, hi, Mac_ { path: pth, tts: tts }));
|
let mac = spanned(lo, hi, Mac_ { path: pth, tts: tts });
|
||||||
let stmt = StmtKind::Mac(mac, style, attrs.into_thin_attrs());
|
Stmt {
|
||||||
spanned(lo, hi, stmt)
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
node: StmtKind::Mac(P((mac, style, attrs.into_thin_attrs()))),
|
||||||
|
span: mk_sp(lo, hi),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// if it has a special ident, it's definitely an item
|
// if it has a special ident, it's definitely an item
|
||||||
//
|
//
|
||||||
@ -4017,25 +4013,28 @@ impl<'a> Parser<'a> {
|
|||||||
followed by a semicolon");
|
followed by a semicolon");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spanned(lo, hi, StmtKind::Decl(
|
Stmt {
|
||||||
P(spanned(lo, hi, DeclKind::Item(
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
span: mk_sp(lo, hi),
|
||||||
|
node: StmtKind::Item({
|
||||||
self.mk_item(
|
self.mk_item(
|
||||||
lo, hi, id /*id is good here*/,
|
lo, hi, id /*id is good here*/,
|
||||||
ItemKind::Mac(spanned(lo, hi,
|
ItemKind::Mac(spanned(lo, hi, Mac_ { path: pth, tts: tts })),
|
||||||
Mac_ { path: pth, tts: tts })),
|
Visibility::Inherited,
|
||||||
Visibility::Inherited, attrs)))),
|
attrs)
|
||||||
ast::DUMMY_NODE_ID))
|
}),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Bad copy of attrs
|
// FIXME: Bad copy of attrs
|
||||||
let restrictions = self.restrictions | Restrictions::NO_NONINLINE_MOD;
|
let restrictions = self.restrictions | Restrictions::NO_NONINLINE_MOD;
|
||||||
match self.with_res(restrictions,
|
match self.with_res(restrictions,
|
||||||
|this| this.parse_item_(attrs.clone(), false, true))? {
|
|this| this.parse_item_(attrs.clone(), false, true))? {
|
||||||
Some(i) => {
|
Some(i) => Stmt {
|
||||||
let hi = i.span.hi;
|
id: ast::DUMMY_NODE_ID,
|
||||||
let decl = P(spanned(lo, hi, DeclKind::Item(i)));
|
span: mk_sp(lo, i.span.hi),
|
||||||
spanned(lo, hi, StmtKind::Decl(decl, ast::DUMMY_NODE_ID))
|
node: StmtKind::Item(i),
|
||||||
}
|
},
|
||||||
None => {
|
None => {
|
||||||
let unused_attrs = |attrs: &[_], s: &mut Self| {
|
let unused_attrs = |attrs: &[_], s: &mut Self| {
|
||||||
if attrs.len() > 0 {
|
if attrs.len() > 0 {
|
||||||
@ -4059,9 +4058,11 @@ impl<'a> Parser<'a> {
|
|||||||
// Remainder are line-expr stmts.
|
// Remainder are line-expr stmts.
|
||||||
let e = self.parse_expr_res(
|
let e = self.parse_expr_res(
|
||||||
Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into_thin_attrs()))?;
|
Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into_thin_attrs()))?;
|
||||||
let hi = e.span.hi;
|
Stmt {
|
||||||
let stmt = StmtKind::Expr(e, ast::DUMMY_NODE_ID);
|
id: ast::DUMMY_NODE_ID,
|
||||||
spanned(lo, hi, stmt)
|
span: mk_sp(lo, e.span.hi),
|
||||||
|
node: StmtKind::Expr(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -4107,7 +4108,7 @@ impl<'a> Parser<'a> {
|
|||||||
let mut expr = None;
|
let mut expr = None;
|
||||||
|
|
||||||
while !self.eat(&token::CloseDelim(token::Brace)) {
|
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
|
s
|
||||||
} else if self.token == token::Eof {
|
} else if self.token == token::Eof {
|
||||||
break;
|
break;
|
||||||
@ -4115,60 +4116,13 @@ impl<'a> Parser<'a> {
|
|||||||
// Found only `;` or `}`.
|
// Found only `;` or `}`.
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
match node {
|
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, &mut expr)?;
|
||||||
}
|
}
|
||||||
StmtKind::Mac(mac, MacStmtStyle::NoBraces, attrs) => {
|
StmtKind::Mac(mac) => {
|
||||||
// statement macro without braces; might be an
|
self.handle_macro_in_block(mac.unwrap(), span, &mut stmts, &mut expr)?;
|
||||||
// expr depending on whether a semicolon follows
|
|
||||||
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,
|
|
||||||
&mut expr)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
token::CloseDelim(token::Brace) => {
|
|
||||||
// if a block ends in `m!(arg)` without
|
|
||||||
// a `;`, it must be an expr
|
|
||||||
expr = Some(self.mk_mac_expr(span.lo, span.hi,
|
|
||||||
m.and_then(|x| x.node),
|
|
||||||
attrs));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
stmts.push(Spanned {
|
|
||||||
node: StmtKind::Mac(m, style, attrs),
|
|
||||||
span: span
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => { // all other kinds of statements:
|
_ => { // all other kinds of statements:
|
||||||
let mut hi = span.hi;
|
let mut hi = span.hi;
|
||||||
@ -4177,7 +4131,8 @@ impl<'a> Parser<'a> {
|
|||||||
hi = self.last_span.hi;
|
hi = self.last_span.hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
stmts.push(Spanned {
|
stmts.push(Stmt {
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: node,
|
node: node,
|
||||||
span: mk_sp(span.lo, hi)
|
span: mk_sp(span.lo, hi)
|
||||||
});
|
});
|
||||||
@ -4194,6 +4149,60 @@ impl<'a> Parser<'a> {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_macro_in_block(&mut self,
|
||||||
|
(mac, style, attrs): (ast::Mac, MacStmtStyle, ThinAttributes),
|
||||||
|
span: Span,
|
||||||
|
stmts: &mut Vec<Stmt>,
|
||||||
|
last_block_expr: &mut Option<P<Expr>>)
|
||||||
|
-> 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, 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, stmts, last_block_expr)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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();
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
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,
|
fn handle_expression_like_statement(&mut self,
|
||||||
e: P<Expr>,
|
e: P<Expr>,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -4219,15 +4228,17 @@ impl<'a> Parser<'a> {
|
|||||||
hi: self.last_span.hi,
|
hi: self.last_span.hi,
|
||||||
expn_id: span.expn_id,
|
expn_id: span.expn_id,
|
||||||
};
|
};
|
||||||
stmts.push(Spanned {
|
stmts.push(Stmt {
|
||||||
node: StmtKind::Semi(e, ast::DUMMY_NODE_ID),
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
node: StmtKind::Semi(e),
|
||||||
span: span_with_semi,
|
span: span_with_semi,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
token::CloseDelim(token::Brace) => *last_block_expr = Some(e),
|
token::CloseDelim(token::Brace) => *last_block_expr = Some(e),
|
||||||
_ => {
|
_ => {
|
||||||
stmts.push(Spanned {
|
stmts.push(Stmt {
|
||||||
node: StmtKind::Expr(e, ast::DUMMY_NODE_ID),
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
node: StmtKind::Expr(e),
|
||||||
span: span
|
span: span
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1606,19 +1606,34 @@ impl<'a> State<'a> {
|
|||||||
pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> {
|
pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> {
|
||||||
try!(self.maybe_print_comment(st.span.lo));
|
try!(self.maybe_print_comment(st.span.lo));
|
||||||
match st.node {
|
match st.node {
|
||||||
ast::StmtKind::Decl(ref decl, _) => {
|
ast::StmtKind::Local(ref loc) => {
|
||||||
try!(self.print_decl(&decl));
|
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));
|
||||||
|
}
|
||||||
|
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.space_if_not_bol());
|
||||||
try!(self.print_expr_outer_attr_style(&expr, false));
|
try!(self.print_expr_outer_attr_style(&expr, false));
|
||||||
}
|
}
|
||||||
ast::StmtKind::Semi(ref expr, _) => {
|
ast::StmtKind::Semi(ref expr) => {
|
||||||
try!(self.space_if_not_bol());
|
try!(self.space_if_not_bol());
|
||||||
try!(self.print_expr_outer_attr_style(&expr, false));
|
try!(self.print_expr_outer_attr_style(&expr, false));
|
||||||
try!(word(&mut self.s, ";"));
|
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.space_if_not_bol());
|
||||||
try!(self.print_outer_attributes(attrs.as_attr_slice()));
|
try!(self.print_outer_attributes(attrs.as_attr_slice()));
|
||||||
let delim = match style {
|
let delim = match style {
|
||||||
@ -2183,7 +2198,7 @@ impl<'a> State<'a> {
|
|||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprKind::Again(opt_ident) => {
|
ast::ExprKind::Continue(opt_ident) => {
|
||||||
try!(word(&mut self.s, "continue"));
|
try!(word(&mut self.s, "continue"));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
if let Some(ident) = opt_ident {
|
if let Some(ident) = opt_ident {
|
||||||
@ -2291,29 +2306,6 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
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));
|
|
||||||
}
|
|
||||||
self.end()
|
|
||||||
}
|
|
||||||
ast::DeclKind::Item(ref item) => self.print_item(&item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
|
pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, &ident.name.as_str()));
|
try!(word(&mut self.s, &ident.name.as_str()));
|
||||||
self.ann.post(self, NodeIdent(&ident))
|
self.ann.post(self, NodeIdent(&ident))
|
||||||
|
@ -63,10 +63,6 @@ impl Visitor for NodeCounter {
|
|||||||
self.count += 1;
|
self.count += 1;
|
||||||
walk_pat(self, p)
|
walk_pat(self, p)
|
||||||
}
|
}
|
||||||
fn visit_decl(&mut self, d: &Decl) {
|
|
||||||
self.count += 1;
|
|
||||||
walk_decl(self, d)
|
|
||||||
}
|
|
||||||
fn visit_expr(&mut self, ex: &Expr) {
|
fn visit_expr(&mut self, ex: &Expr) {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
walk_expr(self, ex)
|
walk_expr(self, ex)
|
||||||
|
@ -65,7 +65,6 @@ pub trait Visitor: Sized {
|
|||||||
fn visit_stmt(&mut self, s: &Stmt) { walk_stmt(self, s) }
|
fn visit_stmt(&mut self, s: &Stmt) { walk_stmt(self, s) }
|
||||||
fn visit_arm(&mut self, a: &Arm) { walk_arm(self, a) }
|
fn visit_arm(&mut self, a: &Arm) { walk_arm(self, a) }
|
||||||
fn visit_pat(&mut self, p: &Pat) { walk_pat(self, p) }
|
fn visit_pat(&mut self, p: &Pat) { walk_pat(self, p) }
|
||||||
fn visit_decl(&mut self, d: &Decl) { walk_decl(self, d) }
|
|
||||||
fn visit_expr(&mut self, ex: &Expr) { walk_expr(self, ex) }
|
fn visit_expr(&mut self, ex: &Expr) { walk_expr(self, ex) }
|
||||||
fn visit_expr_post(&mut self, _ex: &Expr) { }
|
fn visit_expr_post(&mut self, _ex: &Expr) { }
|
||||||
fn visit_ty(&mut self, t: &Ty) { walk_ty(self, t) }
|
fn visit_ty(&mut self, t: &Ty) { walk_ty(self, t) }
|
||||||
@ -597,11 +596,13 @@ pub fn walk_block<V: Visitor>(visitor: &mut V, block: &Block) {
|
|||||||
|
|
||||||
pub fn walk_stmt<V: Visitor>(visitor: &mut V, statement: &Stmt) {
|
pub fn walk_stmt<V: Visitor>(visitor: &mut V, statement: &Stmt) {
|
||||||
match statement.node {
|
match statement.node {
|
||||||
StmtKind::Decl(ref declaration, _) => visitor.visit_decl(declaration),
|
StmtKind::Local(ref local) => visitor.visit_local(local),
|
||||||
StmtKind::Expr(ref expression, _) | StmtKind::Semi(ref expression, _) => {
|
StmtKind::Item(ref item) => visitor.visit_item(item),
|
||||||
|
StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => {
|
||||||
visitor.visit_expr(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);
|
visitor.visit_mac(mac);
|
||||||
for attr in attrs.as_attr_slice() {
|
for attr in attrs.as_attr_slice() {
|
||||||
visitor.visit_attribute(attr);
|
visitor.visit_attribute(attr);
|
||||||
@ -610,13 +611,6 @@ pub fn walk_stmt<V: Visitor>(visitor: &mut V, statement: &Stmt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_decl<V: Visitor>(visitor: &mut V, declaration: &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: Visitor>(_: &mut V, _: &Mac) {
|
pub fn walk_mac<V: Visitor>(_: &mut V, _: &Mac) {
|
||||||
// Empty!
|
// Empty!
|
||||||
}
|
}
|
||||||
@ -745,7 +739,7 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expression: &Expr) {
|
|||||||
}
|
}
|
||||||
visitor.visit_path(path, expression.id)
|
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);
|
walk_opt_sp_ident(visitor, opt_sp_ident);
|
||||||
}
|
}
|
||||||
ExprKind::Ret(ref optional_expression) => {
|
ExprKind::Ret(ref optional_expression) => {
|
||||||
|
@ -13,7 +13,6 @@ use deriving::generic::ty::*;
|
|||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast::{MetaItem, Expr};
|
use syntax::ast::{MetaItem, Expr};
|
||||||
use syntax::codemap::respan;
|
|
||||||
use syntax::ext::base::{ExtCtxt, Annotatable};
|
use syntax::ext::base::{ExtCtxt, Annotatable};
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
@ -152,6 +151,9 @@ fn stmt_let_undescore(cx: &mut ExtCtxt,
|
|||||||
span: sp,
|
span: sp,
|
||||||
attrs: None,
|
attrs: None,
|
||||||
});
|
});
|
||||||
let decl = respan(sp, ast::DeclKind::Local(local));
|
ast::Stmt {
|
||||||
respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
node: ast::StmtKind::Local(local),
|
||||||
|
span: sp,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ use self::Position::*;
|
|||||||
use fmt_macros as parse;
|
use fmt_macros as parse;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::respan;
|
|
||||||
use syntax::ext::base::*;
|
use syntax::ext::base::*;
|
||||||
use syntax::ext::base;
|
use syntax::ext::base;
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
@ -443,12 +442,14 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
|
|
||||||
let name = ecx.ident_of(name);
|
let name = ecx.ident_of(name);
|
||||||
let item = ecx.item(sp, name, vec![], st);
|
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.
|
// Wrap the declaration in a block so that it forms a single expression.
|
||||||
ecx.expr_block(ecx.block(sp,
|
ecx.expr_block(ecx.block(sp, vec![stmt], Some(ecx.expr_ident(sp, name))))
|
||||||
vec![respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))],
|
|
||||||
Some(ecx.expr_ident(sp, name))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Actually builds the expression which the iformat! block will be expanded
|
/// Actually builds the expression which the iformat! block will be expanded
|
||||||
|
Loading…
x
Reference in New Issue
Block a user