diff --git a/syntex_syntax/src/ast.rs b/syntex_syntax/src/ast.rs
index d220508a..cb79c609 100644
--- a/syntex_syntax/src/ast.rs
+++ b/syntex_syntax/src/ast.rs
@@ -10,7 +10,6 @@
// The Rust abstract syntax tree.
-pub use self::Pat_::*;
pub use self::StructFieldKind::*;
pub use self::TyParamBound::*;
pub use self::UnsafeSource::*;
@@ -521,7 +520,7 @@ pub struct Block {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Pat {
pub id: NodeId,
- pub node: Pat_,
+ pub node: PatKind,
pub span: Span,
}
@@ -552,47 +551,53 @@ pub enum BindingMode {
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Pat_ {
+pub enum PatKind {
/// Represents a wildcard pattern (`_`)
- PatWild,
+ Wild,
- /// A PatIdent may either be a new bound variable,
- /// or a nullary enum (in which case the third field
- /// is None).
+ /// A `PatKind::Ident` may either be a new bound variable,
+ /// or a unit struct/variant pattern, or a const pattern (in the last two cases
+ /// the third field must be `None`).
///
- /// In the nullary enum case, the parser can't determine
+ /// In the unit or const pattern case, the parser can't determine
/// which it is. The resolver determines this, and
- /// records this pattern's NodeId in an auxiliary
- /// set (of "PatIdents that refer to nullary enums")
- PatIdent(BindingMode, SpannedIdent, Option
>),
+ /// records this pattern's `NodeId` in an auxiliary
+ /// set (of "PatIdents that refer to unit patterns or constants").
+ Ident(BindingMode, SpannedIdent, Option
>),
+ /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
+ /// The `bool` is `true` in the presence of a `..`.
+ Struct(Path, Vec>, bool),
+
+ /// A tuple struct/variant pattern `Variant(x, y, z)`.
/// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
- PatEnum(Path, Option>>),
+ TupleStruct(Path, Option>>),
+
+ /// A path pattern.
+ /// Such pattern can be resolved to a unit struct/variant or a constant.
+ Path(Path),
/// An associated const named using the qualified path `::CONST` or
/// `::CONST`. Associated consts from inherent impls can be
/// referred to as simply `T::CONST`, in which case they will end up as
- /// PatEnum, and the resolver will have to sort that out.
- PatQPath(QSelf, Path),
+ /// PatKind::Enum, and the resolver will have to sort that out.
+ QPath(QSelf, Path),
- /// Destructuring of a struct, e.g. `Foo {x, y, ..}`
- /// The `bool` is `true` in the presence of a `..`
- PatStruct(Path, Vec>, bool),
/// A tuple pattern `(a, b)`
- PatTup(Vec>),
+ Tup(Vec
>),
/// A `box` pattern
- PatBox(P),
+ Box(P),
/// A reference pattern, e.g. `&mut (a, b)`
- PatRegion(P, Mutability),
+ Ref(P, Mutability),
/// A literal
- PatLit(P),
+ Lit(P),
/// A range pattern, e.g. `1...2`
- PatRange(P, P),
+ Range(P, P),
/// `[a, b, ..i, y, z]` is represented as:
- /// `PatVec(box [a, b], Some(i), box [y, z])`
- PatVec(Vec>, Option
>, Vec
>),
+ /// `PatKind::Vec(box [a, b], Some(i), box [y, z])`
+ Vec(Vec
>, Option
>, Vec
>),
/// A macro pattern; pre-expansion
- PatMac(Mac),
+ Mac(Mac),
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
@@ -1609,7 +1614,7 @@ impl Arg {
}),
pat: P(Pat {
id: DUMMY_NODE_ID,
- node: PatIdent(BindingMode::ByValue(mutability), path, None),
+ node: PatKind::Ident(BindingMode::ByValue(mutability), path, None),
span: span
}),
id: DUMMY_NODE_ID
diff --git a/syntex_syntax/src/ast_util.rs b/syntex_syntax/src/ast_util.rs
index e22cdab9..5d55b6f8 100644
--- a/syntex_syntax/src/ast_util.rs
+++ b/syntex_syntax/src/ast_util.rs
@@ -69,7 +69,7 @@ pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> P {
let spanned = codemap::Spanned{ span: s, node: i };
P(Pat {
id: id,
- node: PatIdent(BindingMode::ByValue(Mutability::Immutable), spanned, None),
+ node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), spanned, None),
span: s
})
}
@@ -348,7 +348,7 @@ pub fn compute_id_range_for_fn_body(fk: FnKind,
/// and false otherwise.
pub fn pat_is_ident(pat: P) -> bool {
match pat.node {
- ast::PatIdent(..) => true,
+ PatKind::Ident(..) => true,
_ => false,
}
}
diff --git a/syntex_syntax/src/ext/base.rs b/syntex_syntax/src/ext/base.rs
index 1f90c687..3d183985 100644
--- a/syntex_syntax/src/ext/base.rs
+++ b/syntex_syntax/src/ext/base.rs
@@ -11,7 +11,7 @@
pub use self::SyntaxExtension::*;
use ast;
-use ast::Name;
+use ast::{Name, PatKind};
use codemap;
use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
use errors::DiagnosticBuilder;
@@ -307,7 +307,7 @@ impl MacResult for MacEager {
return Some(P(ast::Pat {
id: ast::DUMMY_NODE_ID,
span: e.span,
- node: ast::PatLit(e),
+ node: PatKind::Lit(e),
}));
}
}
@@ -359,7 +359,7 @@ impl DummyResult {
pub fn raw_pat(sp: Span) -> ast::Pat {
ast::Pat {
id: ast::DUMMY_NODE_ID,
- node: ast::PatWild,
+ node: PatKind::Wild,
span: sp,
}
}
diff --git a/syntex_syntax/src/ext/build.rs b/syntex_syntax/src/ext/build.rs
index 38af8353..0eb42f17 100644
--- a/syntex_syntax/src/ext/build.rs
+++ b/syntex_syntax/src/ext/build.rs
@@ -9,7 +9,7 @@
// except according to those terms.
use abi::Abi;
-use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp};
+use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind};
use attr;
use codemap::{Span, respan, Spanned, DUMMY_SP, Pos};
use ext::base::ExtCtxt;
@@ -166,7 +166,7 @@ pub trait AstBuilder {
fn expr_err(&self, span: Span, expr: P) -> P;
fn expr_try(&self, span: Span, head: P) -> P;
- fn pat(&self, span: Span, pat: ast::Pat_) -> P;
+ fn pat(&self, span: Span, pat: PatKind) -> P;
fn pat_wild(&self, span: Span) -> P;
fn pat_lit(&self, span: Span, expr: P) -> P;
fn pat_ident(&self, span: Span, ident: ast::Ident) -> P;
@@ -805,14 +805,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
- fn pat(&self, span: Span, pat: ast::Pat_) -> P {
+ fn pat(&self, span: Span, pat: PatKind) -> P {
P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span })
}
fn pat_wild(&self, span: Span) -> P {
- self.pat(span, ast::PatWild)
+ self.pat(span, PatKind::Wild)
}
fn pat_lit(&self, span: Span, expr: P) -> P {
- self.pat(span, ast::PatLit(expr))
+ self.pat(span, PatKind::Lit(expr))
}
fn pat_ident(&self, span: Span, ident: ast::Ident) -> P {
let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Immutable);
@@ -823,20 +823,24 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
span: Span,
ident: ast::Ident,
bm: ast::BindingMode) -> P {
- let pat = ast::PatIdent(bm, Spanned{span: span, node: ident}, None);
+ let pat = PatKind::Ident(bm, Spanned{span: span, node: ident}, None);
self.pat(span, pat)
}
fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec>) -> P {
- let pat = ast::PatEnum(path, Some(subpats));
+ let pat = if subpats.is_empty() {
+ PatKind::Path(path)
+ } else {
+ PatKind::TupleStruct(path, Some(subpats))
+ };
self.pat(span, pat)
}
fn pat_struct(&self, span: Span,
path: ast::Path, field_pats: Vec>) -> P {
- let pat = ast::PatStruct(path, field_pats, false);
+ let pat = PatKind::Struct(path, field_pats, false);
self.pat(span, pat)
}
fn pat_tuple(&self, span: Span, pats: Vec>) -> P {
- self.pat(span, ast::PatTup(pats))
+ self.pat(span, PatKind::Tup(pats))
}
fn pat_some(&self, span: Span, pat: P) -> P {
diff --git a/syntex_syntax/src/ext/expand.rs b/syntex_syntax/src/ext/expand.rs
index 96dc0eef..41f8c8fe 100644
--- a/syntex_syntax/src/ext/expand.rs
+++ b/syntex_syntax/src/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, PatMac};
+use ast::{Block, Crate, DeclKind, PatKind};
use ast::{Local, Ident, Mac_, Name};
use ast::{MacStmtStyle, Mrk, Stmt, StmtKind, ItemKind};
use ast::TokenTree;
@@ -678,7 +678,7 @@ fn rename_in_scope(pats: Vec>,
(f(&mut rename_fld, fld, x), rewritten_pats)
}
-/// A visitor that extracts the PatIdent (binding) paths
+/// A visitor that extracts the PatKind::Ident (binding) paths
/// from a given thingy and puts them in a mutable
/// array
#[derive(Clone)]
@@ -689,9 +689,9 @@ struct PatIdentFinder {
impl<'v> Visitor<'v> for PatIdentFinder {
fn visit_pat(&mut self, pattern: &ast::Pat) {
match *pattern {
- ast::Pat { id: _, node: ast::PatIdent(_, ref path1, ref inner), span: _ } => {
+ ast::Pat { id: _, node: PatKind::Ident(_, ref path1, ref inner), span: _ } => {
self.ident_accumulator.push(path1.node);
- // visit optional subpattern of PatIdent:
+ // visit optional subpattern of PatKind::Ident:
if let Some(ref subpat) = *inner {
self.visit_pat(subpat)
}
@@ -702,14 +702,14 @@ impl<'v> Visitor<'v> for PatIdentFinder {
}
}
-/// find the PatIdent paths in a pattern
+/// find the PatKind::Ident paths in a pattern
fn pattern_bindings(pat: &ast::Pat) -> Vec {
let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
name_finder.visit_pat(pat);
name_finder.ident_accumulator
}
-/// find the PatIdent paths in a
+/// find the PatKind::Ident paths in a
fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec {
let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
for arg in &fn_decl.inputs {
@@ -758,12 +758,12 @@ pub fn expand_block_elts(b: P, fld: &mut MacroExpander) -> P {
fn expand_pat(p: P, fld: &mut MacroExpander) -> P {
match p.node {
- PatMac(_) => {}
+ PatKind::Mac(_) => {}
_ => return noop_fold_pat(p, fld)
}
p.clone().map(|ast::Pat {node, span, ..}| {
let (pth, tts) = match node {
- PatMac(mac) => (mac.node.path, mac.node.tts),
+ PatKind::Mac(mac) => (mac.node.path, mac.node.tts),
_ => unreachable!()
};
if pth.segments.len() > 1 {
@@ -855,7 +855,7 @@ impl<'a> Folder for IdentRenamer<'a> {
}
/// A tree-folder that applies every rename in its list to
-/// the idents that are in PatIdent patterns. This is more narrowly
+/// the idents that are in PatKind::Ident patterns. This is more narrowly
/// focused than IdentRenamer, and is needed for FnDecl,
/// where we want to rename the args but not the fn name or the generics etc.
pub struct PatIdentRenamer<'a> {
@@ -865,16 +865,16 @@ pub struct PatIdentRenamer<'a> {
impl<'a> Folder for PatIdentRenamer<'a> {
fn fold_pat(&mut self, pat: P) -> P {
match pat.node {
- ast::PatIdent(..) => {},
+ PatKind::Ident(..) => {},
_ => return noop_fold_pat(pat, self)
}
pat.map(|ast::Pat {id, node, span}| match node {
- ast::PatIdent(binding_mode, Spanned{span: sp, node: ident}, sub) => {
+ PatKind::Ident(binding_mode, Spanned{span: sp, node: ident}, sub) => {
let new_ident = Ident::new(ident.name,
mtwt::apply_renames(self.renames, ident.ctxt));
let new_node =
- ast::PatIdent(binding_mode,
+ PatKind::Ident(binding_mode,
Spanned{span: self.new_span(sp), node: new_ident},
sub.map(|p| self.fold_pat(p)));
ast::Pat {
diff --git a/syntex_syntax/src/feature_gate.rs b/syntex_syntax/src/feature_gate.rs
index 5dfec8da..70bd85c0 100644
--- a/syntex_syntax/src/feature_gate.rs
+++ b/syntex_syntax/src/feature_gate.rs
@@ -27,7 +27,7 @@ use self::AttributeType::*;
use self::AttributeGate::*;
use abi::Abi;
-use ast::NodeId;
+use ast::{NodeId, PatKind};
use ast;
use attr;
use attr::AttrMetaMethods;
@@ -1005,19 +1005,19 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
fn visit_pat(&mut self, pattern: &ast::Pat) {
match pattern.node {
- ast::PatVec(_, Some(_), ref last) if !last.is_empty() => {
+ PatKind::Vec(_, Some(_), ref last) if !last.is_empty() => {
self.gate_feature("advanced_slice_patterns",
pattern.span,
"multiple-element slice matches anywhere \
but at the end of a slice (e.g. \
`[0, ..xs, 0]`) are experimental")
}
- ast::PatVec(..) => {
+ PatKind::Vec(..) => {
self.gate_feature("slice_patterns",
pattern.span,
"slice pattern syntax is experimental");
}
- ast::PatBox(..) => {
+ PatKind::Box(..) => {
self.gate_feature("box_patterns",
pattern.span,
"box pattern syntax is experimental");
diff --git a/syntex_syntax/src/fold.rs b/syntex_syntax/src/fold.rs
index 6df31317..d75e8f79 100644
--- a/syntex_syntax/src/fold.rs
+++ b/syntex_syntax/src/fold.rs
@@ -1119,23 +1119,26 @@ pub fn noop_fold_pat(p: P, folder: &mut T) -> P {
p.map(|Pat {id, node, span}| Pat {
id: folder.new_id(id),
node: match node {
- PatWild => PatWild,
- PatIdent(binding_mode, pth1, sub) => {
- PatIdent(binding_mode,
+ PatKind::Wild => PatKind::Wild,
+ PatKind::Ident(binding_mode, pth1, sub) => {
+ PatKind::Ident(binding_mode,
Spanned{span: folder.new_span(pth1.span),
node: folder.fold_ident(pth1.node)},
sub.map(|x| folder.fold_pat(x)))
}
- PatLit(e) => PatLit(folder.fold_expr(e)),
- PatEnum(pth, pats) => {
- PatEnum(folder.fold_path(pth),
+ PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)),
+ PatKind::TupleStruct(pth, pats) => {
+ PatKind::TupleStruct(folder.fold_path(pth),
pats.map(|pats| pats.move_map(|x| folder.fold_pat(x))))
}
- PatQPath(qself, pth) => {
+ PatKind::Path(pth) => {
+ PatKind::Path(folder.fold_path(pth))
+ }
+ PatKind::QPath(qself, pth) => {
let qself = QSelf {ty: folder.fold_ty(qself.ty), .. qself};
- PatQPath(qself, folder.fold_path(pth))
+ PatKind::QPath(qself, folder.fold_path(pth))
}
- PatStruct(pth, fields, etc) => {
+ PatKind::Struct(pth, fields, etc) => {
let pth = folder.fold_path(pth);
let fs = fields.move_map(|f| {
Spanned { span: folder.new_span(f.span),
@@ -1145,20 +1148,20 @@ pub fn noop_fold_pat(p: P, folder: &mut T) -> P {
is_shorthand: f.node.is_shorthand,
}}
});
- PatStruct(pth, fs, etc)
+ PatKind::Struct(pth, fs, etc)
}
- PatTup(elts) => PatTup(elts.move_map(|x| folder.fold_pat(x))),
- PatBox(inner) => PatBox(folder.fold_pat(inner)),
- PatRegion(inner, mutbl) => PatRegion(folder.fold_pat(inner), mutbl),
- PatRange(e1, e2) => {
- PatRange(folder.fold_expr(e1), folder.fold_expr(e2))
+ PatKind::Tup(elts) => PatKind::Tup(elts.move_map(|x| folder.fold_pat(x))),
+ PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)),
+ PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl),
+ PatKind::Range(e1, e2) => {
+ PatKind::Range(folder.fold_expr(e1), folder.fold_expr(e2))
},
- PatVec(before, slice, after) => {
- PatVec(before.move_map(|x| folder.fold_pat(x)),
+ PatKind::Vec(before, slice, after) => {
+ PatKind::Vec(before.move_map(|x| folder.fold_pat(x)),
slice.map(|x| folder.fold_pat(x)),
after.move_map(|x| folder.fold_pat(x)))
}
- PatMac(mac) => PatMac(folder.fold_mac(mac))
+ PatKind::Mac(mac) => PatKind::Mac(folder.fold_mac(mac))
},
span: folder.new_span(span)
})
diff --git a/syntex_syntax/src/parse/mod.rs b/syntex_syntax/src/parse/mod.rs
index f35c7907..e9723798 100644
--- a/syntex_syntax/src/parse/mod.rs
+++ b/syntex_syntax/src/parse/mod.rs
@@ -677,7 +677,7 @@ mod tests {
use super::*;
use std::rc::Rc;
use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
- use ast::{self, TokenTree};
+ use ast::{self, TokenTree, PatKind};
use abi::Abi;
use attr::{first_attr_value_str_by_name, AttrMetaMethods};
use parse;
@@ -898,7 +898,7 @@ mod tests {
assert!(panictry!(parser.parse_pat())
== P(ast::Pat{
id: ast::DUMMY_NODE_ID,
- node: ast::PatIdent(ast::BindingMode::ByValue(ast::Mutability::Immutable),
+ node: PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Immutable),
Spanned{ span:sp(0, 1),
node: str_to_ident("b")
},
@@ -933,7 +933,7 @@ mod tests {
}),
pat: P(ast::Pat {
id: ast::DUMMY_NODE_ID,
- node: ast::PatIdent(
+ node: PatKind::Ident(
ast::BindingMode::ByValue(ast::Mutability::Immutable),
Spanned{
span: sp(6,7),
@@ -1022,7 +1022,7 @@ mod tests {
impl<'v> ::visit::Visitor<'v> for PatIdentVisitor {
fn visit_pat(&mut self, p: &'v ast::Pat) {
match p.node {
- ast::PatIdent(_ , ref spannedident, _) => {
+ PatKind::Ident(_ , ref spannedident, _) => {
self.spans.push(spannedident.span.clone());
}
_ => {
diff --git a/syntex_syntax/src/parse/parser.rs b/syntex_syntax/src/parse/parser.rs
index af745020..0403f5f7 100644
--- a/syntex_syntax/src/parse/parser.rs
+++ b/syntex_syntax/src/parse/parser.rs
@@ -30,8 +30,7 @@ use ast::MacStmtStyle;
use ast::Mac_;
use ast::{MutTy, Mutability};
use ast::NamedField;
-use ast::{Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange};
-use ast::{PatRegion, PatStruct, PatTup, PatVec, PatWild};
+use ast::{Pat, PatKind};
use ast::{PolyTraitRef, QSelf};
use ast::{Stmt, StmtKind};
use ast::{VariantData, StructField};
@@ -73,6 +72,7 @@ bitflags! {
flags Restrictions: u8 {
const RESTRICTION_STMT_EXPR = 1 << 0,
const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1,
+ const NO_NONINLINE_MOD = 1 << 2,
}
}
@@ -106,6 +106,12 @@ pub enum ParsePub {
No,
}
+#[derive(Clone, Copy, PartialEq)]
+pub enum SemiColonMode {
+ Break,
+ Ignore,
+}
+
/// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
/// dropped into the token stream, which happens while parsing the result of
/// macro expansion). Placement of these is not as complex as I feared it would
@@ -599,7 +605,7 @@ impl<'a> Parser<'a> {
/// Check if the next token is `tok`, and return `true` if so.
///
- /// This method is will automatically add `tok` to `expected_tokens` if `tok` is not
+ /// This method will automatically add `tok` to `expected_tokens` if `tok` is not
/// encountered.
pub fn check(&mut self, tok: &token::Token) -> bool {
let is_present = self.token == *tok;
@@ -841,6 +847,15 @@ impl<'a> Parser<'a> {
return Ok((v, returned));
}
+ /// Eat and discard tokens until one of `kets` is encountered. Respects token trees,
+ /// passes through any errors encountered. Used for error recovery.
+ pub fn eat_to_tokens(&mut self, kets: &[&token::Token]) {
+ self.parse_seq_to_before_tokens(kets,
+ seq_sep_none(),
+ |p| p.parse_token_tree(),
+ |mut e| e.cancel());
+ }
+
/// Parse a sequence, including the closing delimiter. The function
/// f must consume tokens until reaching the next separator or
/// closing bracket.
@@ -851,7 +866,7 @@ impl<'a> Parser<'a> {
-> PResult<'a, Vec> where
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
{
- let val = try!(self.parse_seq_to_before_end(ket, sep, f));
+ let val = self.parse_seq_to_before_end(ket, sep, f);
self.bump();
Ok(val)
}
@@ -862,24 +877,53 @@ impl<'a> Parser<'a> {
pub fn parse_seq_to_before_end(&mut self,
ket: &token::Token,
sep: SeqSep,
- mut f: F)
- -> PResult<'a, Vec> where
- F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
+ f: F)
+ -> Vec
+ where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
+ {
+ self.parse_seq_to_before_tokens(&[ket], sep, f, |mut e| e.emit())
+ }
+
+ // `fe` is an error handler.
+ fn parse_seq_to_before_tokens(&mut self,
+ kets: &[&token::Token],
+ sep: SeqSep,
+ mut f: F,
+ mut fe: Fe)
+ -> Vec
+ where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
+ Fe: FnMut(DiagnosticBuilder)
{
let mut first: bool = true;
let mut v = vec!();
- while self.token != *ket {
+ while !kets.contains(&&self.token) {
match sep.sep {
- Some(ref t) => {
- if first { first = false; }
- else { try!(self.expect(t)); }
- }
- _ => ()
+ Some(ref t) => {
+ if first {
+ first = false;
+ } else {
+ if let Err(e) = self.expect(t) {
+ fe(e);
+ break;
+ }
+ }
+ }
+ _ => ()
+ }
+ if sep.trailing_sep_allowed && kets.iter().any(|k| self.check(k)) {
+ break;
+ }
+
+ match f(self) {
+ Ok(t) => v.push(t),
+ Err(e) => {
+ fe(e);
+ break;
+ }
}
- if sep.trailing_sep_allowed && self.check(ket) { break; }
- v.push(try!(f(self)));
}
- return Ok(v);
+
+ v
}
/// Parse a sequence, including the closing delimiter. The function
@@ -894,7 +938,7 @@ impl<'a> Parser<'a> {
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
{
try!(self.expect(bra));
- let result = try!(self.parse_seq_to_before_end(ket, sep, f));
+ let result = self.parse_seq_to_before_end(ket, sep, f);
self.bump();
Ok(result)
}
@@ -930,7 +974,7 @@ impl<'a> Parser<'a> {
{
let lo = self.span.lo;
try!(self.expect(bra));
- let result = try!(self.parse_seq_to_before_end(ket, sep, f));
+ let result = self.parse_seq_to_before_end(ket, sep, f);
let hi = self.span.hi;
self.bump();
Ok(spanned(lo, hi, result))
@@ -1217,7 +1261,25 @@ impl<'a> Parser<'a> {
};
(ident, TraitItemKind::Const(ty, default))
} else {
- let (constness, unsafety, abi) = try!(p.parse_fn_front_matter());
+ let (constness, unsafety, abi) = match p.parse_fn_front_matter() {
+ Ok(cua) => cua,
+ Err(e) => {
+ loop {
+ p.bump();
+ if p.token == token::Semi {
+ p.bump();
+ break;
+ }
+
+ if p.token == token::OpenDelim(token::DelimToken::Brace) {
+ try!(p.parse_token_tree());
+ break;
+ }
+ }
+
+ return Err(e);
+ }
+ };
let ident = try!(p.parse_ident());
let mut generics = try!(p.parse_generics());
@@ -2290,14 +2352,37 @@ impl<'a> Parser<'a> {
while self.token != token::CloseDelim(token::Brace) {
if self.eat(&token::DotDot) {
- base = Some(try!(self.parse_expr()));
+ match self.parse_expr() {
+ Ok(e) => {
+ base = Some(e);
+ }
+ Err(mut e) => {
+ e.emit();
+ self.recover_stmt();
+ }
+ }
break;
}
- fields.push(try!(self.parse_field()));
- try!(self.commit_expr(&fields.last().unwrap().expr,
- &[token::Comma],
- &[token::CloseDelim(token::Brace)]));
+ match self.parse_field() {
+ Ok(f) => fields.push(f),
+ Err(mut e) => {
+ e.emit();
+ self.recover_stmt();
+ break;
+ }
+ }
+
+ match self.commit_expr(&fields.last().unwrap().expr,
+ &[token::Comma],
+ &[token::CloseDelim(token::Brace)]) {
+ Ok(()) => {}
+ Err(mut e) => {
+ e.emit();
+ self.recover_stmt();
+ break;
+ }
+ }
}
hi = self.span.hi;
@@ -2642,45 +2727,16 @@ impl<'a> Parser<'a> {
// yet.
maybe_whole!(deref self, NtTT);
- // this is the fall-through for the 'match' below.
- // invariants: the current token is not a left-delimiter,
- // not an EOF, and not the desired right-delimiter (if
- // it were, parse_seq_to_before_end would have prevented
- // reaching this point.
- fn parse_non_delim_tt_tok<'b>(p: &mut Parser<'b>) -> PResult<'b, TokenTree> {
- maybe_whole!(deref p, NtTT);
- match p.token {
- token::CloseDelim(_) => {
- let token_str = p.this_token_to_string();
- let mut err = p.fatal(
- &format!("incorrect close delimiter: `{}`", token_str));
- // This is a conservative error: only report the last unclosed delimiter. The
- // previous unclosed delimiters could actually be closed! The parser just hasn't
- // gotten to them yet.
- if let Some(&sp) = p.open_braces.last() {
- err.span_note(sp, "unclosed delimiter");
- };
- Err(err)
- },
- /* we ought to allow different depths of unquotation */
- token::Dollar | token::SubstNt(..) if p.quote_depth > 0 => {
- p.parse_unquoted()
- }
- _ => {
- Ok(TokenTree::Token(p.span, p.bump_and_get()))
- }
- }
- }
-
match self.token {
token::Eof => {
- let open_braces = self.open_braces.clone();
let mut err: DiagnosticBuilder<'a> =
- self.fatal("this file contains an un-closed delimiter");
- for sp in &open_braces {
+ self.diagnostic().struct_span_err(self.span,
+ "this file contains an un-closed delimiter");
+ for sp in &self.open_braces {
err.span_help(*sp, "did you mean to close this delimiter?");
}
- return Err(err);
+
+ Err(err)
},
token::OpenDelim(delim) => {
// The span for beginning of the delimited section
@@ -2692,11 +2748,9 @@ impl<'a> Parser<'a> {
self.bump();
// Parse the token trees within the delimiters
- let tts = try!(self.parse_seq_to_before_end(
- &token::CloseDelim(delim),
- seq_sep_none(),
- |p| p.parse_token_tree()
- ));
+ let tts = self.parse_seq_to_before_end(&token::CloseDelim(delim),
+ seq_sep_none(),
+ |p| p.parse_token_tree());
// Parse the close delimiter.
let close_span = self.span;
@@ -2713,7 +2767,35 @@ impl<'a> Parser<'a> {
close_span: close_span,
})))
},
- _ => parse_non_delim_tt_tok(self),
+ _ => {
+ // invariants: the current token is not a left-delimiter,
+ // not an EOF, and not the desired right-delimiter (if
+ // it were, parse_seq_to_before_end would have prevented
+ // reaching this point.
+ maybe_whole!(deref self, NtTT);
+ match self.token {
+ token::CloseDelim(_) => {
+ let token_str = self.this_token_to_string();
+ let mut err = self.diagnostic().struct_span_err(self.span,
+ &format!("incorrect close delimiter: `{}`", token_str));
+ // This is a conservative error: only report the last unclosed delimiter.
+ // The previous unclosed delimiters could actually be closed! The parser
+ // just hasn't gotten to them yet.
+ if let Some(&sp) = self.open_braces.last() {
+ err.span_note(sp, "unclosed delimiter");
+ };
+
+ Err(err)
+ },
+ /* we ought to allow different depths of unquotation */
+ token::Dollar | token::SubstNt(..) if self.quote_depth > 0 => {
+ self.parse_unquoted()
+ }
+ _ => {
+ Ok(TokenTree::Token(self.span, self.bump_and_get()))
+ }
+ }
+ }
}
}
@@ -3150,8 +3232,8 @@ impl<'a> Parser<'a> {
fn parse_match_expr(&mut self, attrs: ThinAttributes) -> PResult<'a, P> {
let match_span = self.last_span;
let lo = self.last_span.lo;
- let discriminant = try!(self.parse_expr_res(
- RESTRICTION_NO_STRUCT_LITERAL, None));
+ let discriminant = try!(self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL,
+ None));
if let Err(mut e) = self.commit_expr_expecting(&discriminant,
token::OpenDelim(token::Brace)) {
if self.token == token::Token::Semi {
@@ -3163,7 +3245,19 @@ impl<'a> Parser<'a> {
try!(self.parse_inner_attributes()).into_thin_attrs());
let mut arms: Vec = Vec::new();
while self.token != token::CloseDelim(token::Brace) {
- arms.push(try!(self.parse_arm()));
+ match self.parse_arm() {
+ Ok(arm) => arms.push(arm),
+ Err(mut e) => {
+ // Recover by skipping to the end of the block.
+ e.emit();
+ self.recover_stmt();
+ let hi = self.span.hi;
+ if self.token == token::CloseDelim(token::Brace) {
+ self.bump();
+ }
+ return Ok(self.mk_expr(lo, hi, ExprKind::Match(discriminant, arms), attrs));
+ }
+ }
}
let hi = self.span.hi;
self.bump();
@@ -3208,8 +3302,8 @@ impl<'a> Parser<'a> {
/// Evaluate the closure with restrictions in place.
///
/// After the closure is evaluated, restrictions are reset.
- pub fn with_res(&mut self, r: Restrictions, f: F) -> PResult<'a, P>
- where F: FnOnce(&mut Self) -> PResult<'a, P>
+ pub fn with_res(&mut self, r: Restrictions, f: F) -> T
+ where F: FnOnce(&mut Self) -> T
{
let old = self.restrictions;
self.restrictions = r;
@@ -3292,7 +3386,7 @@ impl<'a> Parser<'a> {
self.check(&token::CloseDelim(token::Bracket)) {
slice = Some(P(ast::Pat {
id: ast::DUMMY_NODE_ID,
- node: PatWild,
+ node: PatKind::Wild,
span: self.span,
}));
before_slice = false;
@@ -3370,14 +3464,14 @@ impl<'a> Parser<'a> {
let fieldpath = codemap::Spanned{span:self.last_span, node:fieldname};
let fieldpat = P(ast::Pat{
id: ast::DUMMY_NODE_ID,
- node: PatIdent(bind_type, fieldpath, None),
+ node: PatKind::Ident(bind_type, fieldpath, None),
span: mk_sp(boxed_span_lo, hi),
});
let subpat = if is_box {
P(ast::Pat{
id: ast::DUMMY_NODE_ID,
- node: PatBox(fieldpat),
+ node: PatKind::Box(fieldpat),
span: mk_sp(lo, hi),
})
} else {
@@ -3429,7 +3523,7 @@ impl<'a> Parser<'a> {
token::Underscore => {
// Parse _
self.bump();
- pat = PatWild;
+ pat = PatKind::Wild;
}
token::BinOp(token::And) | token::AndAnd => {
// Parse &pat / &mut pat
@@ -3440,21 +3534,21 @@ impl<'a> Parser<'a> {
}
let subpat = try!(self.parse_pat());
- pat = PatRegion(subpat, mutbl);
+ pat = PatKind::Ref(subpat, mutbl);
}
token::OpenDelim(token::Paren) => {
// Parse (pat,pat,pat,...) as tuple pattern
self.bump();
let fields = try!(self.parse_pat_tuple_elements());
try!(self.expect(&token::CloseDelim(token::Paren)));
- pat = PatTup(fields);
+ pat = PatKind::Tup(fields);
}
token::OpenDelim(token::Bracket) => {
// Parse [pat,pat,...] as slice pattern
self.bump();
let (before, slice, after) = try!(self.parse_pat_vec_elements());
try!(self.expect(&token::CloseDelim(token::Bracket)));
- pat = PatVec(before, slice, after);
+ pat = PatKind::Vec(before, slice, after);
}
_ => {
// At this point, token != _, &, &&, (, [
@@ -3468,7 +3562,7 @@ impl<'a> Parser<'a> {
} else if self.eat_keyword(keywords::Box) {
// Parse box pat
let subpat = try!(self.parse_pat());
- pat = PatBox(subpat);
+ pat = PatKind::Box(subpat);
} else if self.is_path_start() {
// Parse pattern starting with a path
if self.token.is_plain_ident() && self.look_ahead(1, |t| *t != token::DotDotDot &&
@@ -3487,7 +3581,7 @@ impl<'a> Parser<'a> {
let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
seq_sep_none(), |p| p.parse_token_tree()));
let mac = Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT };
- pat = PatMac(codemap::Spanned {node: mac,
+ pat = PatKind::Mac(codemap::Spanned {node: mac,
span: mk_sp(lo, self.last_span.hi)});
} else {
// Parse ident @ pat
@@ -3513,7 +3607,7 @@ impl<'a> Parser<'a> {
let begin = self.mk_expr(lo, hi, ExprKind::Path(qself, path), None);
self.bump();
let end = try!(self.parse_pat_range_end());
- pat = PatRange(begin, end);
+ pat = PatKind::Range(begin, end);
}
token::OpenDelim(token::Brace) => {
if qself.is_some() {
@@ -3521,9 +3615,13 @@ impl<'a> Parser<'a> {
}
// Parse struct pattern
self.bump();
- let (fields, etc) = try!(self.parse_pat_fields());
+ let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
+ e.emit();
+ self.recover_stmt();
+ (vec![], false)
+ });
self.bump();
- pat = PatStruct(path, fields, etc);
+ pat = PatKind::Struct(path, fields, etc);
}
token::OpenDelim(token::Paren) => {
if qself.is_some() {
@@ -3535,22 +3633,22 @@ impl<'a> Parser<'a> {
self.bump();
self.bump();
try!(self.expect(&token::CloseDelim(token::Paren)));
- pat = PatEnum(path, None);
+ pat = PatKind::TupleStruct(path, None);
} else {
let args = try!(self.parse_enum_variant_seq(
&token::OpenDelim(token::Paren),
&token::CloseDelim(token::Paren),
seq_sep_trailing_allowed(token::Comma),
|p| p.parse_pat()));
- pat = PatEnum(path, Some(args));
+ pat = PatKind::TupleStruct(path, Some(args));
}
}
_ => {
pat = match qself {
// Parse qualified path
- Some(qself) => PatQPath(qself, path),
+ Some(qself) => PatKind::QPath(qself, path),
// Parse nullary enum
- None => PatEnum(path, Some(vec![]))
+ None => PatKind::Path(path)
};
}
}
@@ -3560,9 +3658,9 @@ impl<'a> Parser<'a> {
let begin = try!(self.parse_pat_literal_maybe_minus());
if self.eat(&token::DotDotDot) {
let end = try!(self.parse_pat_range_end());
- pat = PatRange(begin, end);
+ pat = PatKind::Range(begin, end);
} else {
- pat = PatLit(begin);
+ pat = PatKind::Lit(begin);
}
}
}
@@ -3581,7 +3679,7 @@ impl<'a> Parser<'a> {
/// error message when parsing mistakes like ref foo(a,b)
fn parse_pat_ident(&mut self,
binding_mode: ast::BindingMode)
- -> PResult<'a, ast::Pat_> {
+ -> PResult<'a, PatKind> {
if !self.token.is_plain_ident() {
let span = self.span;
let tok_str = self.this_token_to_string();
@@ -3610,7 +3708,7 @@ impl<'a> Parser<'a> {
"expected identifier, found enum pattern"))
}
- Ok(PatIdent(binding_mode, name, sub))
+ Ok(PatKind::Ident(binding_mode, name, sub))
}
/// Parse a local variable declaration
@@ -3675,10 +3773,72 @@ impl<'a> Parser<'a> {
/// Parse a statement. may include decl.
pub fn parse_stmt(&mut self) -> PResult<'a, Option> {
- Ok(try!(self.parse_stmt_()))
+ Ok(self.parse_stmt_())
+ }
+
+ // Eat tokens until we can be relatively sure we reached the end of the
+ // statement. This is something of a best-effort heuristic.
+ //
+ // We terminate when we find an unmatched `}` (without consuming it).
+ fn recover_stmt(&mut self) {
+ self.recover_stmt_(SemiColonMode::Ignore)
+ }
+ // If `break_on_semi` is `Break`, then we will stop consuming tokens after
+ // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
+ // approximate - it can mean we break too early due to macros, but that
+ // shoud only lead to sub-optimal recovery, not inaccurate parsing).
+ fn recover_stmt_(&mut self, break_on_semi: SemiColonMode) {
+ let mut brace_depth = 0;
+ let mut bracket_depth = 0;
+ loop {
+ match self.token {
+ token::OpenDelim(token::DelimToken::Brace) => {
+ brace_depth += 1;
+ self.bump();
+ }
+ token::OpenDelim(token::DelimToken::Bracket) => {
+ bracket_depth += 1;
+ self.bump();
+ }
+ token::CloseDelim(token::DelimToken::Brace) => {
+ if brace_depth == 0 {
+ return;
+ }
+ brace_depth -= 1;
+ self.bump();
+ }
+ token::CloseDelim(token::DelimToken::Bracket) => {
+ bracket_depth -= 1;
+ if bracket_depth < 0 {
+ bracket_depth = 0;
+ }
+ self.bump();
+ }
+ token::Eof => return,
+ token::Semi => {
+ self.bump();
+ if break_on_semi == SemiColonMode::Break &&
+ brace_depth == 0 &&
+ bracket_depth == 0 {
+ return;
+ }
+ }
+ _ => {
+ self.bump()
+ }
+ }
+ }
}
- fn parse_stmt_(&mut self) -> PResult<'a, Option> {
+ fn parse_stmt_(&mut self) -> Option {
+ self.parse_stmt_without_recovery().unwrap_or_else(|mut e| {
+ e.emit();
+ self.recover_stmt_(SemiColonMode::Break);
+ None
+ })
+ }
+
+ fn parse_stmt_without_recovery(&mut self) -> PResult<'a, Option> {
maybe_whole!(Some deref self, NtStmt);
let attrs = try!(self.parse_outer_attributes());
@@ -3767,7 +3927,9 @@ impl<'a> Parser<'a> {
}
} else {
// FIXME: Bad copy of attrs
- match try!(self.parse_item_(attrs.clone(), false, true)) {
+ let restrictions = self.restrictions | NO_NONINLINE_MOD;
+ match try!(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)));
@@ -3834,7 +3996,7 @@ impl<'a> Parser<'a> {
let lo = self.span.lo;
try!(self.expect(&token::OpenDelim(token::Brace)));
Ok((try!(self.parse_inner_attributes()),
- try!(self.parse_block_tail(lo, BlockCheckMode::Default))))
+ try!(self.parse_block_tail(lo, BlockCheckMode::Default))))
}
/// Parse the rest of a block expression or function body
@@ -3844,7 +4006,7 @@ impl<'a> Parser<'a> {
let mut expr = None;
while !self.eat(&token::CloseDelim(token::Brace)) {
- let Spanned {node, span} = if let Some(s) = try!(self.parse_stmt_()) {
+ let Spanned {node, span} = if let Some(s) = self.parse_stmt_() {
s
} else {
// Found only `;` or `}`.
@@ -3929,17 +4091,21 @@ impl<'a> Parser<'a> {
}))
}
- fn handle_expression_like_statement(
- &mut self,
- e: P,
- span: Span,
- stmts: &mut Vec,
- last_block_expr: &mut Option>) -> PResult<'a, ()> {
+ fn handle_expression_like_statement(&mut self,
+ e: P,
+ span: Span,
+ stmts: &mut Vec,
+ last_block_expr: &mut Option>)
+ -> PResult<'a, ()> {
// expression without semicolon
if classify::expr_requires_semi_to_be_stmt(&e) {
// Just check for errors and recover; do not eat semicolon yet.
- try!(self.commit_stmt(&[],
- &[token::Semi, token::CloseDelim(token::Brace)]));
+ if let Err(mut e) =
+ self.commit_stmt(&[], &[token::Semi, token::CloseDelim(token::Brace)])
+ {
+ e.emit();
+ self.recover_stmt();
+ }
}
match self.token {
@@ -4172,8 +4338,8 @@ impl<'a> Parser<'a> {
fn forbid_lifetime(&mut self) -> PResult<'a, ()> {
if self.token.is_lifetime() {
let span = self.span;
- return Err(self.span_fatal(span, "lifetime parameters must be declared \
- prior to type parameters"))
+ return Err(self.diagnostic().struct_span_err(span, "lifetime parameters must be \
+ declared prior to type parameters"))
}
Ok(())
}
@@ -4301,7 +4467,8 @@ impl<'a> Parser<'a> {
fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
-> PResult<'a, (Vec , bool)> {
let sp = self.span;
- let mut args: Vec> =
+ let mut variadic = false;
+ let args: Vec > =
try!(self.parse_unspanned_seq(
&token::OpenDelim(token::Paren),
&token::CloseDelim(token::Paren),
@@ -4312,38 +4479,36 @@ impl<'a> Parser<'a> {
if allow_variadic {
if p.token != token::CloseDelim(token::Paren) {
let span = p.span;
- return Err(p.span_fatal(span,
- "`...` must be last in argument list for variadic function"))
+ p.span_err(span,
+ "`...` must be last in argument list for variadic function");
}
} else {
let span = p.span;
- return Err(p.span_fatal(span,
- "only foreign functions are allowed to be variadic"))
+ p.span_err(span,
+ "only foreign functions are allowed to be variadic");
}
+ variadic = true;
Ok(None)
} else {
- Ok(Some(try!(p.parse_arg_general(named_args))))
+ match p.parse_arg_general(named_args) {
+ Ok(arg) => Ok(Some(arg)),
+ Err(mut e) => {
+ e.emit();
+ p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
+ Ok(None)
+ }
+ }
}
}
));
- let variadic = match args.pop() {
- Some(None) => true,
- Some(x) => {
- // Need to put back that last arg
- args.push(x);
- false
- }
- None => false
- };
+ let args: Vec<_> = args.into_iter().filter_map(|x| x).collect();
if variadic && args.is_empty() {
self.span_err(sp,
"variadic function must be declared with at least one named argument");
}
- let args = args.into_iter().map(|x| x.unwrap()).collect();
-
Ok((args, variadic))
}
@@ -4520,11 +4685,11 @@ impl<'a> Parser<'a> {
token::Comma => {
self.bump();
let sep = seq_sep_trailing_allowed(token::Comma);
- let mut fn_inputs = try!(self.parse_seq_to_before_end(
+ let mut fn_inputs = self.parse_seq_to_before_end(
&token::CloseDelim(token::Paren),
sep,
parse_arg_fn
- ));
+ );
fn_inputs.insert(0, Arg::new_self(explicit_self_sp, mutbl_self, $self_id));
fn_inputs
}
@@ -4543,8 +4708,7 @@ impl<'a> Parser<'a> {
let fn_inputs = match explicit_self {
SelfKind::Static => {
let sep = seq_sep_trailing_allowed(token::Comma);
- try!(self.parse_seq_to_before_end(&token::CloseDelim(token::Paren),
- sep, parse_arg_fn))
+ self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)
}
SelfKind::Value(id) => parse_remaining_arguments!(id),
SelfKind::Region(_,_,id) => parse_remaining_arguments!(id),
@@ -4575,11 +4739,11 @@ impl<'a> Parser<'a> {
} else {
try!(self.expect(&token::BinOp(token::Or)));
try!(self.parse_obsolete_closure_kind());
- let args = try!(self.parse_seq_to_before_end(
+ let args = self.parse_seq_to_before_end(
&token::BinOp(token::Or),
seq_sep_trailing_allowed(token::Comma),
|p| p.parse_fn_block_arg()
- ));
+ );
self.bump();
args
}
@@ -4741,8 +4905,8 @@ impl<'a> Parser<'a> {
// eat a matched-delimiter token tree:
let delim = try!(self.expect_open_delim());
let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
- seq_sep_none(),
- |p| p.parse_token_tree()));
+ seq_sep_none(),
+ |p| p.parse_token_tree()));
let m_ = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
let m: ast::Mac = codemap::Spanned { node: m_,
span: mk_sp(lo,
@@ -5096,11 +5260,8 @@ impl<'a> Parser<'a> {
self.push_mod_path(id, outer_attrs);
try!(self.expect(&token::OpenDelim(token::Brace)));
let mod_inner_lo = self.span.lo;
- let old_owns_directory = self.owns_directory;
- self.owns_directory = true;
let attrs = try!(self.parse_inner_attributes());
let m = try!(self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo));
- self.owns_directory = old_owns_directory;
self.pop_mod_path();
Ok((id, ItemKind::Mod(m), Some(attrs)))
}
@@ -5177,7 +5338,17 @@ impl<'a> Parser<'a> {
let paths = Parser::default_submod_path(id, &dir_path, self.sess.codemap());
- if !self.owns_directory {
+ if self.restrictions.contains(NO_NONINLINE_MOD) {
+ let msg =
+ "Cannot declare a non-inline module inside a block unless it has a path attribute";
+ let mut err = self.diagnostic().struct_span_err(id_sp, msg);
+ if paths.path_exists {
+ let msg = format!("Maybe `use` the module `{}` instead of redeclaring it",
+ paths.name);
+ err.span_note(id_sp, &msg);
+ }
+ return Err(err);
+ } else if !self.owns_directory {
let mut err = self.diagnostic().struct_span_err(id_sp,
"cannot declare a new module at this location");
let this_module = match self.mod_path_stack.last() {
@@ -5801,8 +5972,8 @@ impl<'a> Parser<'a> {
// eat a matched-delimiter token tree:
let delim = try!(self.expect_open_delim());
let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
- seq_sep_none(),
- |p| p.parse_token_tree()));
+ seq_sep_none(),
+ |p| p.parse_token_tree()));
// single-variant-enum... :
let m = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
let m: ast::Mac = codemap::Spanned { node: m,
diff --git a/syntex_syntax/src/print/pprust.rs b/syntex_syntax/src/print/pprust.rs
index 393baac6..602aef8d 100644
--- a/syntex_syntax/src/print/pprust.rs
+++ b/syntex_syntax/src/print/pprust.rs
@@ -11,7 +11,7 @@
pub use self::AnnNode::*;
use abi::{self, Abi};
-use ast::{self, TokenTree, BlockCheckMode};
+use ast::{self, TokenTree, BlockCheckMode, PatKind};
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
use ast::Attribute;
use attr::ThinAttributesExt;
@@ -2463,8 +2463,8 @@ impl<'a> State<'a> {
/* Pat isn't normalized, but the beauty of it
is that it doesn't matter */
match pat.node {
- ast::PatWild => try!(word(&mut self.s, "_")),
- ast::PatIdent(binding_mode, ref path1, ref sub) => {
+ PatKind::Wild => try!(word(&mut self.s, "_")),
+ PatKind::Ident(binding_mode, ref path1, ref sub) => {
match binding_mode {
ast::BindingMode::ByRef(mutbl) => {
try!(self.word_nbsp("ref"));
@@ -2484,24 +2484,25 @@ impl<'a> State<'a> {
None => ()
}
}
- ast::PatEnum(ref path, ref args_) => {
+ PatKind::TupleStruct(ref path, ref args_) => {
try!(self.print_path(path, true, 0));
match *args_ {
None => try!(word(&mut self.s, "(..)")),
Some(ref args) => {
- if !args.is_empty() {
- try!(self.popen());
- try!(self.commasep(Inconsistent, &args[..],
- |s, p| s.print_pat(&p)));
- try!(self.pclose());
- }
+ try!(self.popen());
+ try!(self.commasep(Inconsistent, &args[..],
+ |s, p| s.print_pat(&p)));
+ try!(self.pclose());
}
}
}
- ast::PatQPath(ref qself, ref path) => {
+ PatKind::Path(ref path) => {
+ try!(self.print_path(path, true, 0));
+ }
+ PatKind::QPath(ref qself, ref path) => {
try!(self.print_qpath(path, qself, false));
}
- ast::PatStruct(ref path, ref fields, etc) => {
+ PatKind::Struct(ref path, ref fields, etc) => {
try!(self.print_path(path, true, 0));
try!(self.nbsp());
try!(self.word_space("{"));
@@ -2524,7 +2525,7 @@ impl<'a> State<'a> {
try!(space(&mut self.s));
try!(word(&mut self.s, "}"));
}
- ast::PatTup(ref elts) => {
+ PatKind::Tup(ref elts) => {
try!(self.popen());
try!(self.commasep(Inconsistent,
&elts[..],
@@ -2534,32 +2535,32 @@ impl<'a> State<'a> {
}
try!(self.pclose());
}
- ast::PatBox(ref inner) => {
+ PatKind::Box(ref inner) => {
try!(word(&mut self.s, "box "));
try!(self.print_pat(&inner));
}
- ast::PatRegion(ref inner, mutbl) => {
+ PatKind::Ref(ref inner, mutbl) => {
try!(word(&mut self.s, "&"));
if mutbl == ast::Mutability::Mutable {
try!(word(&mut self.s, "mut "));
}
try!(self.print_pat(&inner));
}
- ast::PatLit(ref e) => try!(self.print_expr(&e)),
- ast::PatRange(ref begin, ref end) => {
+ PatKind::Lit(ref e) => try!(self.print_expr(&**e)),
+ PatKind::Range(ref begin, ref end) => {
try!(self.print_expr(&begin));
try!(space(&mut self.s));
try!(word(&mut self.s, "..."));
try!(self.print_expr(&end));
}
- ast::PatVec(ref before, ref slice, ref after) => {
+ PatKind::Vec(ref before, ref slice, ref after) => {
try!(word(&mut self.s, "["));
try!(self.commasep(Inconsistent,
&before[..],
|s, p| s.print_pat(&p)));
if let Some(ref p) = *slice {
if !before.is_empty() { try!(self.word_space(",")); }
- if p.node != ast::PatWild {
+ if p.node != PatKind::Wild {
try!(self.print_pat(&p));
}
try!(word(&mut self.s, ".."));
@@ -2570,7 +2571,7 @@ impl<'a> State<'a> {
|s, p| s.print_pat(&p)));
try!(word(&mut self.s, "]"));
}
- ast::PatMac(ref m) => try!(self.print_mac(m, token::Paren)),
+ PatKind::Mac(ref m) => try!(self.print_mac(m, token::Paren)),
}
self.ann.post(self, NodePat(pat))
}
@@ -2677,7 +2678,7 @@ impl<'a> State<'a> {
let m = match *explicit_self {
ast::SelfKind::Static => ast::Mutability::Immutable,
_ => match decl.inputs[0].pat.node {
- ast::PatIdent(ast::BindingMode::ByValue(m), _, _) => m,
+ PatKind::Ident(ast::BindingMode::ByValue(m), _, _) => m,
_ => ast::Mutability::Immutable
}
};
@@ -2968,7 +2969,7 @@ impl<'a> State<'a> {
ast::TyKind::Infer if is_closure => try!(self.print_pat(&input.pat)),
_ => {
match input.pat.node {
- ast::PatIdent(_, ref path1, _) if
+ PatKind::Ident(_, ref path1, _) if
path1.node.name ==
parse::token::special_idents::invalid.name => {
// Do nothing.
diff --git a/syntex_syntax/src/visit.rs b/syntex_syntax/src/visit.rs
index ca9e4cc7..4c18b063 100644
--- a/syntex_syntax/src/visit.rs
+++ b/syntex_syntax/src/visit.rs
@@ -427,46 +427,49 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
match pattern.node {
- PatEnum(ref path, ref opt_children) => {
+ PatKind::TupleStruct(ref path, ref opt_children) => {
visitor.visit_path(path, pattern.id);
if let Some(ref children) = *opt_children {
walk_list!(visitor, visit_pat, children);
}
}
- PatQPath(ref qself, ref path) => {
+ PatKind::Path(ref path) => {
+ visitor.visit_path(path, pattern.id);
+ }
+ PatKind::QPath(ref qself, ref path) => {
visitor.visit_ty(&qself.ty);
visitor.visit_path(path, pattern.id)
}
- PatStruct(ref path, ref fields, _) => {
+ PatKind::Struct(ref path, ref fields, _) => {
visitor.visit_path(path, pattern.id);
for field in fields {
visitor.visit_ident(field.span, field.node.ident);
visitor.visit_pat(&field.node.pat)
}
}
- PatTup(ref tuple_elements) => {
+ PatKind::Tup(ref tuple_elements) => {
walk_list!(visitor, visit_pat, tuple_elements);
}
- PatBox(ref subpattern) |
- PatRegion(ref subpattern, _) => {
+ PatKind::Box(ref subpattern) |
+ PatKind::Ref(ref subpattern, _) => {
visitor.visit_pat(subpattern)
}
- PatIdent(_, ref pth1, ref optional_subpattern) => {
+ PatKind::Ident(_, ref pth1, ref optional_subpattern) => {
visitor.visit_ident(pth1.span, pth1.node);
walk_opt!(visitor, visit_pat, optional_subpattern);
}
- PatLit(ref expression) => visitor.visit_expr(expression),
- PatRange(ref lower_bound, ref upper_bound) => {
+ PatKind::Lit(ref expression) => visitor.visit_expr(expression),
+ PatKind::Range(ref lower_bound, ref upper_bound) => {
visitor.visit_expr(lower_bound);
visitor.visit_expr(upper_bound)
}
- PatWild => (),
- PatVec(ref prepatterns, ref slice_pattern, ref postpatterns) => {
+ PatKind::Wild => (),
+ PatKind::Vec(ref prepatterns, ref slice_pattern, ref postpatterns) => {
walk_list!(visitor, visit_pat, prepatterns);
walk_opt!(visitor, visit_pat, slice_pattern);
walk_list!(visitor, visit_pat, postpatterns);
}
- PatMac(ref mac) => visitor.visit_mac(mac),
+ PatKind::Mac(ref mac) => visitor.visit_mac(mac),
}
}