Fix fallout

This commit is contained in:
Jeffrey Seyfried 2016-06-17 02:30:01 +00:00
parent b5dbe01a2c
commit 962d5c16b5
21 changed files with 308 additions and 385 deletions

View File

@ -237,19 +237,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 {
hir::TypeBinding {
id: b.id,
@ -1579,21 +1566,29 @@ impl<'a> LoweringContext<'a> {
fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
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 {
node: hir::StmtDecl(self.lower_decl(d), id),
node: hir::StmtExpr(self.lower_expr(e), s.id),
span: s.span,
}
}
StmtKind::Expr(ref e, id) => {
StmtKind::Semi(ref e) => {
Spanned {
node: hir::StmtExpr(self.lower_expr(e), id),
span: s.span,
}
}
StmtKind::Semi(ref e, id) => {
Spanned {
node: hir::StmtSemi(self.lower_expr(e), id),
node: hir::StmtSemi(self.lower_expr(e), s.id),
span: s.span,
}
}

View File

@ -1005,11 +1005,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'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) {
run_lints!(self, check_expr_post, early_passes, e);
}

View File

@ -195,7 +195,6 @@ pub trait EarlyLintPass: LintPass {
fn check_stmt(&mut self, _: &EarlyContext, _: &ast::Stmt) { }
fn check_arm(&mut self, _: &EarlyContext, _: &ast::Arm) { }
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_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }

View File

@ -365,12 +365,9 @@ impl EarlyLintPass for UnusedParens {
fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) {
let (value, msg) = match s.node {
ast::StmtKind::Decl(ref decl, _) => match decl.node {
ast::DeclKind::Local(ref local) => match local.init {
Some(ref value) => (value, "assigned value"),
None => return
},
_ => return
ast::StmtKind::Local(ref local) => match local.init {
Some(ref value) => (value, "assigned value"),
None => return
},
_ => return
};

View File

@ -31,10 +31,10 @@ use syntax::attr;
use syntax::parse::token;
use syntax::codemap::{Span, DUMMY_SP};
use syntax::ast::{Block, Crate, DeclKind};
use syntax::ast::{Block, Crate};
use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind};
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::visit::{self, Visitor};
@ -84,17 +84,11 @@ impl<'b> Resolver<'b> {
}
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
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.

View File

@ -1421,8 +1421,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx,
}
fn visit_stmt(&mut self, s: &ast::Stmt) {
let id = s.node.id();
self.process_macro_use(s.span, id.unwrap());
self.process_macro_use(s.span, s.id);
visit::walk_stmt(self, s)
}

View File

@ -29,7 +29,6 @@ use ptr::P;
use std::fmt;
use std::rc::Rc;
use std::borrow::Cow;
use std::hash::{Hash, Hasher};
use serialize::{Encodable, Decodable, Encoder, Decoder};
@ -795,10 +794,7 @@ pub struct Stmt {
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))
}
}
@ -821,15 +817,6 @@ pub enum StmtKind {
}
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)
}
@ -868,12 +855,6 @@ impl Local {
}
}
impl Decl {
pub fn attrs(&self) -> &[Attribute] {
HasAttrs::attrs(self)
}
}
/// represents one arm of a 'match'
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Arm {

View File

@ -16,8 +16,8 @@ pub use self::IntType::*;
use ast;
use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaItemKind};
use ast::{Stmt, StmtKind, DeclKind};
use ast::{Expr, Item, Local, Decl};
use ast::{Stmt, StmtKind};
use ast::{Expr, Item, Local};
use codemap::{Span, Spanned, spanned, dummy_spanned};
use codemap::BytePos;
use errors::Handler;
@ -924,38 +924,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 {
fn attrs(&self) -> &[Attribute] {
match *self {
StmtKind::Decl(ref decl, _) => decl.attrs(),
StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => expr.attrs(),
StmtKind::Mac(_, _, ref attrs) => attrs.attrs(),
StmtKind::Local(ref local) => local.attrs(),
StmtKind::Item(ref item) => item.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 {
match self {
StmtKind::Decl(decl, id) => StmtKind::Decl(decl.map_attrs(f), id),
StmtKind::Expr(expr, id) => StmtKind::Expr(expr.map_attrs(f), id),
StmtKind::Semi(expr, id) => StmtKind::Semi(expr.map_attrs(f), id),
StmtKind::Mac(mac, style, attrs) =>
StmtKind::Mac(mac, style, attrs.map_attrs(f)),
StmtKind::Local(local) => StmtKind::Local(local.map_attrs(f)),
StmtKind::Item(item) => StmtKind::Item(item.map_attrs(f)),
StmtKind::Expr(expr) => StmtKind::Expr(expr.map_attrs(f)),
StmtKind::Semi(expr) => StmtKind::Semi(expr.map_attrs(f)),
StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, style, attrs)| {
(mac, style, attrs.map_attrs(f))
})),
}
}
}
@ -982,4 +972,4 @@ derive_has_attrs_from_field! {
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 }

View File

@ -212,17 +212,10 @@ impl<'a> fold::Folder for StripUnconfigured<'a> {
}
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
if !is_item {
self.visit_stmt_or_expr_attrs(stmt.attrs());
match stmt.node {
ast::StmtKind::Item(_) => {}
_ => self.visit_stmt_or_expr_attrs(stmt.attrs()),
}
self.configure(stmt).map(|stmt| fold::noop_fold_stmt(stmt, self))

View File

@ -202,10 +202,11 @@ impl<F> IdentMacroExpander for F
// Use a macro because forwarding to a simple function has type system issues
macro_rules! make_stmts_default {
($me:expr) => {
$me.make_expr().map(|e| {
SmallVector::one(codemap::respan(
e.span, ast::StmtKind::Expr(e, ast::DUMMY_NODE_ID)))
})
$me.make_expr().map(|e| SmallVector::one(ast::Stmt {
id: ast::DUMMY_NODE_ID,
span: e.span,
node: ast::StmtKind::Expr(e),
}))
}
}
@ -399,10 +400,11 @@ impl MacResult for DummyResult {
}
fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> {
Some(SmallVector::one(
codemap::respan(self.span,
ast::StmtKind::Expr(DummyResult::raw_expr(self.span),
ast::DUMMY_NODE_ID))))
Some(SmallVector::one(ast::Stmt {
id: ast::DUMMY_NODE_ID,
node: ast::StmtKind::Expr(DummyResult::raw_expr(self.span)),
span: self.span,
}))
}
}

View File

@ -508,7 +508,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
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,
@ -527,8 +531,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
span: sp,
attrs: None,
});
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,
@ -552,8 +559,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
span: sp,
attrs: None,
});
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>,
@ -562,8 +572,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
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> {

View File

@ -8,7 +8,7 @@
// 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;
@ -444,25 +444,25 @@ fn expand_stmt(stmt: Stmt, fld: &mut MacroExpander) -> SmallVector<Stmt> {
};
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_attr_vec(), 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,
});
}
}
@ -471,73 +471,53 @@ fn expand_stmt(stmt: Stmt, fld: &mut MacroExpander) -> SmallVector<Stmt> {
// 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),
}
}

View File

@ -102,10 +102,6 @@ pub trait Folder : Sized {
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))
}
@ -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 {
TypeBinding {
id: fld.new_id(b.id),
@ -1312,44 +1295,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))
}
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)| {
let mac = folder.fold_mac(mac);
let attrs = attrs.map_thin_attrs(|attrs| fold_attrs(attrs, folder));
(mac, semi, attrs)
})),
span: span,
})
}
}

View File

@ -47,13 +47,9 @@ pub fn expr_is_simple_block(e: &ast::Expr) -> bool {
/// seen the semicolon, and thus don't need another.
pub fn stmt_ends_with_semi(stmt: &ast::StmtKind) -> bool {
match *stmt {
ast::StmtKind::Decl(ref d, _) => {
match d.node {
ast::DeclKind::Local(_) => true,
ast::DeclKind::Item(_) => false,
}
}
ast::StmtKind::Expr(ref e, _) => expr_requires_semi_to_be_stmt(e),
ast::StmtKind::Local(_) => true,
ast::StmtKind::Item(_) => false,
ast::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(e),
ast::StmtKind::Semi(..) => false,
ast::StmtKind::Mac(..) => false,
}

View File

@ -841,7 +841,7 @@ mod tests {
#[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 {
@ -855,8 +855,8 @@ mod tests {
),
}),
span: sp(0,1),
attrs: None}),
ast::DUMMY_NODE_ID),
attrs: None})),
id: ast::DUMMY_NODE_ID,
span: sp(0,1)}))
}
@ -932,7 +932,7 @@ mod tests {
}
},
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,
@ -950,8 +950,8 @@ mod tests {
),
}),
span: sp(17,18),
attrs: None,}),
ast::DUMMY_NODE_ID),
attrs: None,})),
id: ast::DUMMY_NODE_ID,
span: sp(17,19)}),
expr: None,
id: ast::DUMMY_NODE_ID,

View File

@ -16,7 +16,7 @@ use ast::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind};
use ast::Block;
use ast::{BlockCheckMode, CaptureBy};
use ast::{Constness, Crate, CrateConfig};
use ast::{Decl, DeclKind, Defaultness};
use ast::Defaultness;
use ast::{EMPTY_CTXT, EnumDef};
use ast::{Expr, ExprKind, RangeLimits};
use ast::{Field, FnDecl};
@ -3804,13 +3804,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
fn parse_name_and_ty(&mut self, pr: Visibility,
attrs: Vec<Attribute> ) -> PResult<'a, StructField> {
@ -3923,12 +3916,12 @@ impl<'a> Parser<'a> {
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_thin_attrs())?),
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) {
@ -3979,9 +3972,12 @@ impl<'a> Parser<'a> {
};
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, ctxt: EMPTY_CTXT });
Stmt {
id: ast::DUMMY_NODE_ID,
node: StmtKind::Mac(P((mac, style, attrs.into_thin_attrs()))),
span: mk_sp(lo, hi),
}
} else {
// if it has a special ident, it's definitely an item
//
@ -3995,25 +3991,28 @@ impl<'a> Parser<'a> {
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))
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 {
@ -4037,9 +4036,11 @@ impl<'a> Parser<'a> {
// 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)
Stmt {
id: ast::DUMMY_NODE_ID,
span: mk_sp(lo, e.span.hi),
node: StmtKind::Expr(e),
}
}
}
}))
@ -4085,7 +4086,7 @@ impl<'a> Parser<'a> {
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;
@ -4093,60 +4094,13 @@ impl<'a> Parser<'a> {
// Found only `;` or `}`.
continue;
};
match node {
StmtKind::Expr(e, _) => {
StmtKind::Expr(e) => {
self.handle_expression_like_statement(e, span, &mut stmts, &mut expr)?;
}
StmtKind::Mac(mac, MacStmtStyle::NoBraces, attrs) => {
// statement macro without braces; might be an
// 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
});
}
}
StmtKind::Mac(mac) => {
self.handle_macro_in_block(mac.unwrap(), span, &mut stmts, &mut expr)?;
}
_ => { // all other kinds of statements:
let mut hi = span.hi;
@ -4155,7 +4109,8 @@ impl<'a> Parser<'a> {
hi = self.last_span.hi;
}
stmts.push(Spanned {
stmts.push(Stmt {
id: ast::DUMMY_NODE_ID,
node: node,
span: mk_sp(span.lo, hi)
});
@ -4172,6 +4127,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,
e: P<Expr>,
span: Span,
@ -4197,15 +4206,17 @@ impl<'a> Parser<'a> {
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
});
}

View File

@ -1592,19 +1592,34 @@ impl<'a> State<'a> {
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.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.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.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()));
let delim = match style {
@ -2277,29 +2292,6 @@ impl<'a> State<'a> {
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<()> {
try!(word(&mut self.s, &ident.name.as_str()));
self.ann.post(self, NodeIdent(&ident))

View File

@ -63,10 +63,6 @@ impl<'v> Visitor<'v> for NodeCounter {
self.count += 1;
walk_pat(self, p)
}
fn visit_decl(&mut self, d: &'v Decl) {
self.count += 1;
walk_decl(self, d)
}
fn visit_expr(&mut self, ex: &'v Expr) {
self.count += 1;
walk_expr(self, ex)

View File

@ -64,7 +64,6 @@ pub trait Visitor<'v> : Sized {
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) }
@ -613,11 +612,13 @@ pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v 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() {
visitor.visit_attribute(attr);
@ -626,13 +627,6 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
}
}
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) {
// Empty!
}

View File

@ -13,7 +13,7 @@ use deriving::generic::ty::*;
use syntax::ast;
use syntax::ast::{MetaItem, Expr};
use syntax::codemap::{Span, respan, DUMMY_SP};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
@ -151,6 +151,9 @@ fn stmt_let_undescore(cx: &mut ExtCtxt,
span: sp,
attrs: None,
});
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,
}
}

View File

@ -14,7 +14,7 @@ use self::Position::*;
use fmt_macros as parse;
use syntax::ast;
use syntax::codemap::{Span, respan, DUMMY_SP};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::ext::base::*;
use syntax::ext::base;
use syntax::ext::build::AstBuilder;
@ -441,12 +441,14 @@ impl<'a, 'b> Context<'a, 'b> {
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![respan(sp, ast::StmtKind::Decl(P(decl), ast::DUMMY_NODE_ID))],
Some(ecx.expr_ident(sp, name))))
ecx.expr_block(ecx.block(sp, vec![stmt], Some(ecx.expr_ident(sp, name))))
}
/// Actually builds the expression which the iformat! block will be expanded