diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-26 02:16:55 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-26 02:17:27 +0000 |
| commit | 8748cd92d06328af657934f6728183c10f92eefe (patch) | |
| tree | 560b5d24cb0a944210e292ed47dd754af0ed1828 /src/libsyntax | |
| parent | 33ea1e330ccdda85a1501078c0b997fd27ce1e72 (diff) | |
| parent | f6fe5b6a3e3daf4c10410aec3802576f08c6343f (diff) | |
| download | rust-8748cd92d06328af657934f6728183c10f92eefe.tar.gz rust-8748cd92d06328af657934f6728183c10f92eefe.zip | |
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`.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 51 | ||||
| -rw-r--r-- | src/libsyntax/attr.rs | 43 | ||||
| -rw-r--r-- | src/libsyntax/config.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 27 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 124 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 77 | ||||
| -rw-r--r-- | src/libsyntax/parse/classify.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 191 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 50 | ||||
| -rw-r--r-- | src/libsyntax/util/node_count.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 18 |
13 files changed, 289 insertions, 349 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c8ea514600e..51f42a678ce 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -27,7 +27,6 @@ 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}; @@ -811,41 +810,35 @@ impl UnOp { } /// 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 (must have unit type): - Expr(P<Expr>, NodeId), + /// An item definition. + Item(P<Item>), - /// Expr with trailing semi-colon (may have any type): - Semi(P<Expr>, NodeId), + /// Expr without trailing semi-colon (must have unit type). + Expr(P<Expr>), - Mac(P<Mac>, MacStmtStyle, ThinAttributes), -} + /// Expr with trailing semi-colon (may have any type). + 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, - } - } + Mac(P<(Mac, MacStmtStyle, ThinAttributes)>), } #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -875,16 +868,6 @@ pub struct Local { 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'. /// /// E.g. `0...10 => { println!("match!") }` as in @@ -1053,7 +1036,7 @@ pub enum ExprKind { /// 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>>), diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 09d7f28157a..34d07291bf4 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -16,8 +16,7 @@ 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::{Expr, Item, Local, Stmt, StmtKind}; use codemap::{spanned, dummy_spanned, Spanned}; use syntax_pos::{Span, BytePos}; 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 { 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)) + })), } } } @@ -967,4 +956,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 } diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index cc5a68eae3b..961763c6025 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -213,17 +213,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)) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index d1b7546752d..4a715aa1d5b 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -221,10 +221,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), + })) } } @@ -436,10 +437,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, + })) } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index fdf26263330..17655cc1254 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -509,7 +509,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, @@ -528,8 +532,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, @@ -553,8 +560,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>, @@ -563,8 +573,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> { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5e34428a317..ff8d0f81bd0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -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; @@ -439,25 +439,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, + }); } } @@ -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_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), } } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 73c2957bbcf..1dc7f45ddbe 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -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), @@ -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), 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))) ), @@ -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)) } -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, }) } } diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 89110f3160f..4fe4ec7e4c0 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -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, } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index d0863b0551a..28555dc89bc 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -844,7 +844,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 { @@ -858,8 +858,8 @@ mod tests { ), }), span: sp(0,1), - attrs: None}), - ast::DUMMY_NODE_ID), + attrs: None})), + id: ast::DUMMY_NODE_ID, span: sp(0,1)})) } @@ -935,7 +935,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, @@ -953,8 +953,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, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f383b34d1ca..c04d2c37157 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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::EnumDef; use ast::{Expr, ExprKind, RangeLimits}; use ast::{Field, FnDecl}; @@ -2312,14 +2312,14 @@ impl<'a> Parser<'a> { } 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)); @@ -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 fn parse_name_and_ty(&mut self, pr: Visibility, attrs: Vec<Attribute> ) -> PResult<'a, StructField> { @@ -3945,12 +3938,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) { @@ -4001,9 +3994,12 @@ impl<'a> Parser<'a> { }; if id.name == keywords::Invalid.name() { - let mac = P(spanned(lo, hi, Mac_ { path: pth, tts: tts })); - 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_thin_attrs()))), + span: mk_sp(lo, hi), + } } else { // if it has a special ident, it's definitely an item // @@ -4017,25 +4013,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 })), - 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 { @@ -4059,9 +4058,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), + } } } })) @@ -4107,7 +4108,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; @@ -4115,60 +4116,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; @@ -4177,7 +4131,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) }); @@ -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, e: P<Expr>, span: Span, @@ -4219,15 +4228,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 }); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3f466f9e642..a268a6e9605 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1606,19 +1606,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 { @@ -2183,7 +2198,7 @@ impl<'a> State<'a> { 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 { @@ -2291,29 +2306,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)) diff --git a/src/libsyntax/util/node_count.rs b/src/libsyntax/util/node_count.rs index 7c364a1603e..14244bbdddf 100644 --- a/src/libsyntax/util/node_count.rs +++ b/src/libsyntax/util/node_count.rs @@ -63,10 +63,6 @@ impl Visitor for NodeCounter { self.count += 1; 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) { self.count += 1; walk_expr(self, ex) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 9a52c0b32be..aca0c2bcf57 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -65,7 +65,6 @@ pub trait Visitor: Sized { 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_decl(&mut self, d: &Decl) { walk_decl(self, d) } 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) } @@ -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) { 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); @@ -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) { // Empty! } @@ -745,7 +739,7 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expression: &Expr) { } 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) => { |
