};
match found {
Some(e) => {
- try!($p.bump());
+ $p.bump();
return Ok(e);
}
None => ()
{
let found = match ($p).token {
token::Interpolated(token::$constructor(_)) => {
- Some(try!(($p).bump_and_get()))
+ Some(($p).bump_and_get())
}
_ => None
};
{
let found = match ($p).token {
token::Interpolated(token::$constructor(_)) => {
- Some(try!(($p).bump_and_get()))
+ Some(($p).bump_and_get())
}
_ => None
};
{
let found = match ($p).token {
token::Interpolated(token::$constructor(_)) => {
- Some(try!(($p).bump_and_get()))
+ Some(($p).bump_and_get())
}
_ => None
};
{
let found = match ($p).token {
token::Interpolated(token::$constructor(_)) => {
- Some(try!(($p).bump_and_get()))
+ Some(($p).bump_and_get())
}
_ => None
};
{
let found = match ($p).token {
token::Interpolated(token::$constructor(_)) => {
- Some(try!(($p).bump_and_get()))
+ Some(($p).bump_and_get())
}
_ => None
};
Parser::token_to_string(&self.token)
}
- pub fn unexpected_last(&self, t: &token::Token) -> DiagnosticBuilder<'a> {
+ pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
let token_str = Parser::token_to_string(t);
let last_span = self.last_span;
- self.span_fatal(last_span, &format!("unexpected token: `{}`",
- token_str))
+ Err(self.span_fatal(last_span, &format!("unexpected token: `{}`", token_str)))
}
- pub fn unexpected(&mut self) -> DiagnosticBuilder<'a> {
+ pub fn unexpected<T>(&mut self) -> PResult<'a, T> {
match self.expect_one_of(&[], &[]) {
- Err(e) => e,
- Ok(_) => unreachable!()
+ Err(e) => Err(e),
+ Ok(_) => unreachable!(),
}
}
pub fn expect(&mut self, t: &token::Token) -> PResult<'a, ()> {
if self.expected_tokens.is_empty() {
if self.token == *t {
- self.bump()
+ self.bump();
+ Ok(())
} else {
let token_str = Parser::token_to_string(t);
let this_token_str = self.this_token_to_string();
})
}
if edible.contains(&self.token) {
- self.bump()
+ self.bump();
+ Ok(())
} else if inedible.contains(&self.token) {
// leave it in the input
Ok(())
/// true if and only if input was consumed for recovery.
pub fn check_for_erroneous_unit_struct_expecting(&mut self,
expected: &[token::Token])
- -> PResult<'a, bool> {
+ -> bool {
if self.token == token::OpenDelim(token::Brace)
&& expected.iter().all(|t| *t != token::OpenDelim(token::Brace))
&& self.look_ahead(1, |t| *t == token::CloseDelim(token::Brace)) {
// matched; signal non-fatal error and recover.
let span = self.span;
- self.span_err(span,
- "unit-like struct construction is written with no trailing `{ }`");
- try!(self.eat(&token::OpenDelim(token::Brace)));
- try!(self.eat(&token::CloseDelim(token::Brace)));
- Ok(true)
+ self.span_err(span, "unit-like struct construction is written with no trailing `{ }`");
+ self.eat(&token::OpenDelim(token::Brace));
+ self.eat(&token::CloseDelim(token::Brace));
+ true
} else {
- Ok(false)
+ false
}
}
.cloned()
.chain(inedible.iter().cloned())
.collect::<Vec<_>>();
- try!(self.check_for_erroneous_unit_struct_expecting(&expected[..]));
+ self.check_for_erroneous_unit_struct_expecting(&expected[..]);
}
self.expect_one_of(edible, inedible)
}
.cloned()
.chain(inedible.iter().cloned())
.collect::<Vec<_>>();
- try!(self.check_for_erroneous_unit_struct_expecting(&expected));
+ self.check_for_erroneous_unit_struct_expecting(&expected);
}
self.expect_one_of(edible, inedible)
}
pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
self.check_strict_keywords();
- try!(self.check_reserved_keywords());
+ self.check_reserved_keywords();
match self.token {
token::Ident(i, _) => {
- try!(self.bump());
+ self.bump();
Ok(i)
}
token::Interpolated(token::NtIdent(..)) => {
pub fn parse_path_list_item(&mut self) -> PResult<'a, ast::PathListItem> {
let lo = self.span.lo;
- let node = if try!(self.eat_keyword(keywords::SelfValue)) {
+ let node = if self.eat_keyword(keywords::SelfValue) {
let rename = try!(self.parse_rename());
ast::PathListMod { id: ast::DUMMY_NODE_ID, rename: rename }
} else {
/// Consume token 'tok' if it exists. Returns true if the given
/// token was present, false otherwise.
- pub fn eat(&mut self, tok: &token::Token) -> PResult<'a, bool> {
+ pub fn eat(&mut self, tok: &token::Token) -> bool {
let is_present = self.check(tok);
- if is_present { try!(self.bump())}
- Ok(is_present)
+ if is_present { self.bump() }
+ is_present
}
pub fn check_keyword(&mut self, kw: keywords::Keyword) -> bool {
/// If the next token is the given keyword, eat it and return
/// true. Otherwise, return false.
- pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, bool> {
+ pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
if self.check_keyword(kw) {
- try!(self.bump());
- Ok(true)
+ self.bump();
+ true
} else {
- Ok(false)
+ false
}
}
- pub fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> PResult<'a, bool> {
+ pub fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> bool {
if self.token.is_keyword(kw) {
- try!(self.bump());
- Ok(true)
+ self.bump();
+ true
} else {
- Ok(false)
+ false
}
}
/// If the next token is not the given word, signal an error.
/// Otherwise, eat it.
pub fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, ()> {
- if !try!(self.eat_keyword(kw) ){
- self.expect_one_of(&[], &[])
+ if !self.eat_keyword(kw) {
+ self.unexpected()
} else {
Ok(())
}
}
/// Signal an error if the current token is a reserved keyword
- pub fn check_reserved_keywords(&mut self) -> PResult<'a, ()>{
+ pub fn check_reserved_keywords(&mut self) {
if self.token.is_reserved_keyword() {
let token_str = self.this_token_to_string();
- Err(self.fatal(&format!("`{}` is a reserved keyword", token_str)))
- } else {
- Ok(())
+ self.fatal(&format!("`{}` is a reserved keyword", token_str)).emit()
}
}
fn expect_and(&mut self) -> PResult<'a, ()> {
self.expected_tokens.push(TokenType::Token(token::BinOp(token::And)));
match self.token {
- token::BinOp(token::And) => self.bump(),
+ token::BinOp(token::And) => {
+ self.bump();
+ Ok(())
+ }
token::AndAnd => {
let span = self.span;
let lo = span.lo + BytePos(1);
Ok(self.replace_token(token::BinOp(token::And), lo, span.hi))
}
- _ => self.expect_one_of(&[], &[])
+ _ => self.unexpected()
}
}
///
/// This is meant to be used when parsing generics on a path to get the
/// starting token.
- fn eat_lt(&mut self) -> PResult<'a, bool> {
+ fn eat_lt(&mut self) -> bool {
self.expected_tokens.push(TokenType::Token(token::Lt));
match self.token {
- token::Lt => { try!(self.bump()); Ok(true)}
+ token::Lt => {
+ self.bump();
+ true
+ }
token::BinOp(token::Shl) => {
let span = self.span;
let lo = span.lo + BytePos(1);
self.replace_token(token::Lt, lo, span.hi);
- Ok(true)
+ true
}
- _ => Ok(false),
+ _ => false,
}
}
fn expect_lt(&mut self) -> PResult<'a, ()> {
- if !try!(self.eat_lt()) {
- self.expect_one_of(&[], &[])
+ if !self.eat_lt() {
+ self.unexpected()
} else {
Ok(())
}
pub fn expect_gt(&mut self) -> PResult<'a, ()> {
self.expected_tokens.push(TokenType::Token(token::Gt));
match self.token {
- token::Gt => self.bump(),
+ token::Gt => {
+ self.bump();
+ Ok(())
+ }
token::BinOp(token::Shr) => {
let span = self.span;
let lo = span.lo + BytePos(1);
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
{
let val = try!(self.parse_seq_to_before_end(ket, sep, f));
- try!(self.bump());
+ self.bump();
Ok(val)
}
{
try!(self.expect(bra));
let result = try!(self.parse_seq_to_before_end(ket, sep, f));
- try!(self.bump());
+ self.bump();
Ok(result)
}
try!(self.expect(bra));
let result = try!(self.parse_seq_to_before_end(ket, sep, f));
let hi = self.span.hi;
- try!(self.bump());
+ self.bump();
Ok(spanned(lo, hi, result))
}
/// Advance the parser by one token
- pub fn bump(&mut self) -> PResult<'a, ()> {
+ pub fn bump(&mut self) {
self.last_span = self.span;
// Stash token for error recovery (sometimes; clone is not necessarily cheap).
self.last_token = if self.token.is_ident() ||
self.tokens_consumed += 1;
self.expected_tokens.clear();
// check after each token
- self.check_unknown_macro_variable()
+ self.check_unknown_macro_variable();
}
/// Advance the parser by one token and return the bumped token.
- pub fn bump_and_get(&mut self) -> PResult<'a, token::Token> {
+ pub fn bump_and_get(&mut self) -> token::Token {
let old_token = mem::replace(&mut self.token, token::Underscore);
- try!(self.bump());
- Ok(old_token)
+ self.bump();
+ old_token
}
/// EFFECT: replace the current token and span with the given one
let poly_trait_ref = ast::PolyTraitRef { bound_lifetimes: lifetime_defs,
trait_ref: trait_ref,
span: mk_sp(lo, hi)};
- let other_bounds = if try!(self.eat(&token::BinOp(token::Plus)) ){
+ let other_bounds = if self.eat(&token::BinOp(token::Plus)) {
try!(self.parse_ty_param_bounds(BoundParsingMode::Bare))
} else {
P::empty()
*/
let unsafety = try!(self.parse_unsafety());
- let abi = if try!(self.eat_keyword(keywords::Extern) ){
+ let abi = if self.eat_keyword(keywords::Extern) {
try!(self.parse_opt_abi()).unwrap_or(abi::C)
} else {
abi::Rust
self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) &&
self.look_ahead(2, |t| *t == token::Colon)
{
- try!(self.bump());
- try!(self.bump());
- try!(self.bump());
+ self.bump();
+ self.bump();
+ self.bump();
} else if
self.token == token::BinOp(token::And) &&
self.look_ahead(1, |t| *t == token::Colon)
{
- try!(self.bump());
- try!(self.bump());
+ self.bump();
+ self.bump();
} else if
- try!(self.eat(&token::Colon))
+ self.eat(&token::Colon)
{
/* nothing */
} else {
}
pub fn parse_unsafety(&mut self) -> PResult<'a, Unsafety> {
- if try!(self.eat_keyword(keywords::Unsafe)) {
+ if self.eat_keyword(keywords::Unsafe) {
return Ok(Unsafety::Unsafe);
} else {
return Ok(Unsafety::Normal);
let mut attrs = try!(p.parse_outer_attributes());
let lo = p.span.lo;
- let (name, node) = if try!(p.eat_keyword(keywords::Type)) {
+ let (name, node) = if p.eat_keyword(keywords::Type) {
let TyParam {ident, bounds, default, ..} = try!(p.parse_ty_param());
try!(p.expect(&token::Semi));
(ident, TypeTraitItem(bounds, default))
try!(p.expect(&token::Colon));
let ty = try!(p.parse_ty_sum());
let default = if p.check(&token::Eq) {
- try!(p.bump());
+ p.bump();
let expr = try!(p.parse_expr());
try!(p.commit_expr_expecting(&expr, token::Semi));
Some(expr)
let body = match p.token {
token::Semi => {
- try!(p.bump());
+ p.bump();
debug!("parse_trait_methods(): parsing required method");
None
}
/// Parse optional return type [ -> TY ] in function decl
pub fn parse_ret_ty(&mut self) -> PResult<'a, FunctionRetTy> {
- if try!(self.eat(&token::RArrow) ){
- if try!(self.eat(&token::Not) ){
+ if self.eat(&token::RArrow) {
+ if self.eat(&token::Not) {
Ok(NoReturn(self.last_span))
} else {
Ok(Return(try!(self.parse_ty())))
let lo = self.span.lo;
let lhs = try!(self.parse_ty());
- if !try!(self.eat(&token::BinOp(token::Plus)) ){
+ if !self.eat(&token::BinOp(token::Plus)) {
return Ok(lhs);
}
let lo = self.span.lo;
let t = if self.check(&token::OpenDelim(token::Paren)) {
- try!(self.bump());
+ self.bump();
// (t) is a parenthesized ty
// (t,) is the type of a tuple with only one field,
ts.push(try!(self.parse_ty_sum()));
if self.check(&token::Comma) {
last_comma = true;
- try!(self.bump());
+ self.bump();
} else {
last_comma = false;
break;
}
} else if self.check(&token::BinOp(token::Star)) {
// STAR POINTER (bare pointer?)
- try!(self.bump());
+ self.bump();
TyPtr(try!(self.parse_ptr()))
} else if self.check(&token::OpenDelim(token::Bracket)) {
// VECTOR
} else if self.token_is_bare_fn_keyword() {
// BARE FUNCTION
try!(self.parse_ty_bare_fn(Vec::new()))
- } else if try!(self.eat_keyword_noexpect(keywords::Typeof)) {
+ } else if self.eat_keyword_noexpect(keywords::Typeof) {
// TYPEOF
// In order to not be ambiguous, the type must be surrounded by parens.
try!(self.expect(&token::OpenDelim(token::Paren)));
let e = try!(self.parse_expr());
try!(self.expect(&token::CloseDelim(token::Paren)));
TyTypeof(e)
- } else if try!(self.eat_lt()) {
+ } else if self.eat_lt() {
let (qself, path) =
try!(self.parse_qualified_path(NoTypesAllowed));
let path = try!(self.parse_path(LifetimeAndTypesWithoutColons));
if self.check(&token::Not) {
// MACRO INVOCATION
- try!(self.bump());
+ self.bump();
let delim = try!(self.expect_open_delim());
let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
seq_sep_none(),
// NAMED TYPE
TyPath(None, path)
}
- } else if try!(self.eat(&token::Underscore) ){
+ } else if self.eat(&token::Underscore) {
// TYPE TO BE INFERRED
TyInfer
} else {
}
pub fn parse_ptr(&mut self) -> PResult<'a, MutTy> {
- let mutbl = if try!(self.eat_keyword(keywords::Mut) ){
+ let mutbl = if self.eat_keyword(keywords::Mut) {
MutMutable
- } else if try!(self.eat_keyword(keywords::Const) ){
+ } else if self.eat_keyword(keywords::Const) {
MutImmutable
} else {
let span = self.last_span;
/// Parse an argument in a lambda header e.g. |arg, arg|
pub fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
let pat = try!(self.parse_pat());
- let t = if try!(self.eat(&token::Colon) ){
+ let t = if self.eat(&token::Colon) {
try!(self.parse_ty_sum())
} else {
P(Ty {
pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::Expr>>> {
if self.check(&token::Semi) {
- try!(self.bump());
+ self.bump();
Ok(Some(try!(self.parse_expr())))
} else {
Ok(None)
token::Interpolated(token::NtExpr(ref v)) => {
match v.node {
ExprLit(ref lit) => { Ok(lit.node.clone()) }
- _ => { return Err(self.unexpected_last(tok)); }
+ _ => { return self.unexpected_last(tok); }
}
}
token::Literal(lit, suf) => {
Ok(out)
}
- _ => { return Err(self.unexpected_last(tok)); }
+ _ => { return self.unexpected_last(tok); }
}
}
/// Matches lit = true | false | token_lit
pub fn parse_lit(&mut self) -> PResult<'a, Lit> {
let lo = self.span.lo;
- let lit = if try!(self.eat_keyword(keywords::True) ){
+ let lit = if self.eat_keyword(keywords::True) {
LitBool(true)
- } else if try!(self.eat_keyword(keywords::False) ){
+ } else if self.eat_keyword(keywords::False) {
LitBool(false)
} else {
- let token = try!(self.bump_and_get());
+ let token = self.bump_and_get();
let lit = try!(self.lit_from_token(&token));
lit
};
/// matches '-' lit | lit
pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
let minus_lo = self.span.lo;
- let minus_present = try!(self.eat(&token::BinOp(token::Minus)));
+ let minus_present = self.eat(&token::BinOp(token::Minus));
let lo = self.span.lo;
let literal = P(try!(self.parse_lit()));
let hi = self.last_span.hi;
-> PResult<'a, (QSelf, ast::Path)> {
let span = self.last_span;
let self_type = try!(self.parse_ty_sum());
- let mut path = if try!(self.eat_keyword(keywords::As)) {
+ let mut path = if self.eat_keyword(keywords::As) {
try!(self.parse_path(LifetimeAndTypesWithoutColons))
} else {
ast::Path {
pub fn parse_path(&mut self, mode: PathParsingMode) -> PResult<'a, ast::Path> {
// Check for a whole path...
let found = match self.token {
- token::Interpolated(token::NtPath(_)) => Some(try!(self.bump_and_get())),
+ token::Interpolated(token::NtPath(_)) => Some(self.bump_and_get()),
_ => None,
};
if let Some(token::Interpolated(token::NtPath(path))) = found {
}
let lo = self.span.lo;
- let is_global = try!(self.eat(&token::ModSep));
+ let is_global = self.eat(&token::ModSep);
// Parse any number of segments and bound sets. A segment is an
// identifier followed by an optional lifetime and a set of types.
let identifier = try!(self.parse_ident_or_self_type());
// Parse types, optionally.
- let parameters = if try!(self.eat_lt() ){
+ let parameters = if self.eat_lt() {
let (lifetimes, types, bindings) = try!(self.parse_generic_values_after_lt());
ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
types: P::from_vec(types),
bindings: P::from_vec(bindings),
})
- } else if try!(self.eat(&token::OpenDelim(token::Paren)) ){
+ } else if self.eat(&token::OpenDelim(token::Paren)) {
let lo = self.last_span.lo;
let inputs = try!(self.parse_seq_to_end(
seq_sep_trailing_allowed(token::Comma),
|p| p.parse_ty_sum()));
- let output_ty = if try!(self.eat(&token::RArrow) ){
+ let output_ty = if self.eat(&token::RArrow) {
Some(try!(self.parse_ty()))
} else {
None
parameters: parameters });
// Continue only if we see a `::`
- if !try!(self.eat(&token::ModSep) ){
+ if !self.eat(&token::ModSep) {
return Ok(segments);
}
}
let identifier = try!(self.parse_ident_or_self_type());
// If we do not see a `::`, stop.
- if !try!(self.eat(&token::ModSep) ){
+ if !self.eat(&token::ModSep) {
segments.push(ast::PathSegment {
identifier: identifier,
parameters: ast::PathParameters::none()
}
// Check for a type segment.
- if try!(self.eat_lt() ){
+ if self.eat_lt() {
// Consumed `a::b::<`, go look for types
let (lifetimes, types, bindings) = try!(self.parse_generic_values_after_lt());
let parameters = ast::AngleBracketedParameterData {
});
// Consumed `a::b::<T,U>`, check for `::` before proceeding
- if !try!(self.eat(&token::ModSep) ){
+ if !self.eat(&token::ModSep) {
return Ok(segments);
}
} else {
});
// If we do not see a `::`, stop.
- if !try!(self.eat(&token::ModSep) ){
+ if !self.eat(&token::ModSep) {
return Ok(segments);
}
}
match self.token {
token::Lifetime(i) => {
let span = self.span;
- try!(self.bump());
+ self.bump();
return Ok(ast::Lifetime {
id: ast::DUMMY_NODE_ID,
span: span,
token::Lifetime(_) => {
let lifetime = try!(self.parse_lifetime());
let bounds =
- if try!(self.eat(&token::Colon) ){
+ if self.eat(&token::Colon) {
try!(self.parse_lifetimes(token::BinOp(token::Plus)))
} else {
Vec::new()
}
match self.token {
- token::Comma => { try!(self.bump());}
+ token::Comma => { self.bump();}
token::Gt => { return Ok(res); }
token::BinOp(token::Shr) => { return Ok(res); }
_ => {
return Ok(res);
}
- try!(self.bump());
+ self.bump();
}
}
/// Parse mutability declaration (mut/const/imm)
pub fn parse_mutability(&mut self) -> PResult<'a, Mutability> {
- if try!(self.eat_keyword(keywords::Mut) ){
+ if self.eat_keyword(keywords::Mut) {
Ok(MutMutable)
} else {
Ok(MutImmutable)
self.expected_tokens.push(TokenType::Token(token::Gt));
match self.token {
token::OpenDelim(delim) => {
- try!(self.bump());
+ self.bump();
Ok(delim)
},
_ => Err(self.fatal("expected open delimiter")),
// Note: when adding new syntax here, don't forget to adjust Token::can_begin_expr().
match self.token {
token::OpenDelim(token::Paren) => {
- try!(self.bump());
+ self.bump();
let attrs = try!(self.parse_inner_attributes())
.into_thin_attrs()
if self.check(&token::Comma) {
trailing_comma = true;
- try!(self.bump());
+ self.bump();
} else {
trailing_comma = false;
break;
}
}
- try!(self.bump());
+ self.bump();
hi = self.last_span.hi;
return if es.len() == 1 && !trailing_comma {
name: token::SELF_KEYWORD_NAME,
ctxt: _
}, token::Plain) => {
- try!(self.bump());
+ self.bump();
let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
ex = ExprPath(None, path);
hi = self.last_span.hi;
}
token::OpenDelim(token::Bracket) => {
- try!(self.bump());
+ self.bump();
let inner_attrs = try!(self.parse_inner_attributes())
.into_thin_attrs();
if self.check(&token::CloseDelim(token::Bracket)) {
// Empty vector.
- try!(self.bump());
+ self.bump();
ex = ExprVec(Vec::new());
} else {
// Nonempty vector.
let first_expr = try!(self.parse_expr());
if self.check(&token::Semi) {
// Repeating array syntax: [ 0; 512 ]
- try!(self.bump());
+ self.bump();
let count = try!(self.parse_expr());
try!(self.expect(&token::CloseDelim(token::Bracket)));
ex = ExprRepeat(first_expr, count);
} else if self.check(&token::Comma) {
// Vector with two or more elements.
- try!(self.bump());
+ self.bump();
let remaining_exprs = try!(self.parse_seq_to_end(
&token::CloseDelim(token::Bracket),
seq_sep_trailing_allowed(token::Comma),
hi = self.last_span.hi;
}
_ => {
- if try!(self.eat_lt()){
+ if self.eat_lt() {
let (qself, path) =
try!(self.parse_qualified_path(LifetimeAndTypesWithColons));
hi = path.span.hi;
return Ok(self.mk_expr(lo, hi, ExprPath(Some(qself), path), attrs));
}
- if try!(self.eat_keyword(keywords::Move) ){
+ if self.eat_keyword(keywords::Move) {
let lo = self.last_span.lo;
return self.parse_lambda_expr(lo, CaptureByValue, attrs);
}
- if try!(self.eat_keyword(keywords::If)) {
+ if self.eat_keyword(keywords::If) {
return self.parse_if_expr(attrs);
}
- if try!(self.eat_keyword(keywords::For) ){
+ if self.eat_keyword(keywords::For) {
let lo = self.last_span.lo;
return self.parse_for_expr(None, lo, attrs);
}
- if try!(self.eat_keyword(keywords::While) ){
+ if self.eat_keyword(keywords::While) {
let lo = self.last_span.lo;
return self.parse_while_expr(None, lo, attrs);
}
if self.token.is_lifetime() {
let lifetime = self.get_lifetime();
let lo = self.span.lo;
- try!(self.bump());
+ self.bump();
try!(self.expect(&token::Colon));
- if try!(self.eat_keyword(keywords::While) ){
+ if self.eat_keyword(keywords::While) {
return self.parse_while_expr(Some(lifetime), lo, attrs)
}
- if try!(self.eat_keyword(keywords::For) ){
+ if self.eat_keyword(keywords::For) {
return self.parse_for_expr(Some(lifetime), lo, attrs)
}
- if try!(self.eat_keyword(keywords::Loop) ){
+ if self.eat_keyword(keywords::Loop) {
return self.parse_loop_expr(Some(lifetime), lo, attrs)
}
return Err(self.fatal("expected `while`, `for`, or `loop` after a label"))
}
- if try!(self.eat_keyword(keywords::Loop) ){
+ if self.eat_keyword(keywords::Loop) {
let lo = self.last_span.lo;
return self.parse_loop_expr(None, lo, attrs);
}
- if try!(self.eat_keyword(keywords::Continue) ){
+ if self.eat_keyword(keywords::Continue) {
let ex = if self.token.is_lifetime() {
let ex = ExprAgain(Some(Spanned{
node: self.get_lifetime(),
span: self.span
}));
- try!(self.bump());
+ self.bump();
ex
} else {
ExprAgain(None)
let hi = self.last_span.hi;
return Ok(self.mk_expr(lo, hi, ex, attrs));
}
- if try!(self.eat_keyword(keywords::Match) ){
+ if self.eat_keyword(keywords::Match) {
return self.parse_match_expr(attrs);
}
- if try!(self.eat_keyword(keywords::Unsafe) ){
+ if self.eat_keyword(keywords::Unsafe) {
return self.parse_block_expr(
lo,
UnsafeBlock(ast::UserProvided),
attrs);
}
- if try!(self.eat_keyword(keywords::Return) ){
+ if self.eat_keyword(keywords::Return) {
if self.token.can_begin_expr() {
let e = try!(self.parse_expr());
hi = e.span.hi;
} else {
ex = ExprRet(None);
}
- } else if try!(self.eat_keyword(keywords::Break) ){
+ } else if self.eat_keyword(keywords::Break) {
if self.token.is_lifetime() {
ex = ExprBreak(Some(Spanned {
node: self.get_lifetime(),
span: self.span
}));
- try!(self.bump());
+ self.bump();
} else {
ex = ExprBreak(None);
}
// `!`, as an operator, is prefix, so we know this isn't that
if self.check(&token::Not) {
// MACRO INVOCATION expression
- try!(self.bump());
+ self.bump();
let delim = try!(self.expect_open_delim());
let tts = try!(self.parse_seq_to_end(
);
if !prohibited {
// It's a struct literal.
- try!(self.bump());
+ self.bump();
let mut fields = Vec::new();
let mut base = None;
.into_thin_attrs());
while self.token != token::CloseDelim(token::Brace) {
- if try!(self.eat(&token::DotDot) ){
+ if self.eat(&token::DotDot) {
base = Some(try!(self.parse_expr()));
break;
}
)
}
+ // Assuming we have just parsed `.foo` (i.e., a dot and an ident), continue
+ // parsing into an expression.
+ fn parse_dot_suffix(&mut self,
+ ident: Ident,
+ ident_span: Span,
+ self_value: P<Expr>)
+ -> PResult<'a, P<Expr>> {
+ let (_, tys, bindings) = if self.eat(&token::ModSep) {
+ try!(self.expect_lt());
+ try!(self.parse_generic_values_after_lt())
+ } else {
+ (Vec::new(), Vec::new(), Vec::new())
+ };
+
+ if !bindings.is_empty() {
+ let last_span = self.last_span;
+ self.span_err(last_span, "type bindings are only permitted on trait paths");
+ }
+
+ let lo = self_value.span.lo;
+
+ Ok(match self.token {
+ // expr.f() method call.
+ token::OpenDelim(token::Paren) => {
+ let mut es = try!(self.parse_unspanned_seq(
+ &token::OpenDelim(token::Paren),
+ &token::CloseDelim(token::Paren),
+ seq_sep_trailing_allowed(token::Comma),
+ |p| Ok(try!(p.parse_expr()))
+ ));
+ let hi = self.last_span.hi;
+
+ es.insert(0, self_value);
+ let id = spanned(ident_span.lo, ident_span.hi, ident);
+ let nd = self.mk_method_call(id, tys, es);
+ self.mk_expr(lo, hi, nd, None)
+ }
+ // Field access.
+ _ => {
+ if !tys.is_empty() {
+ let last_span = self.last_span;
+ self.span_err(last_span,
+ "field expressions may not \
+ have type parameters");
+ }
+
+ let id = spanned(ident_span.lo, ident_span.hi, ident);
+ let field = self.mk_field(self_value, id);
+ self.mk_expr(lo, ident_span.hi, field, None)
+ }
+ })
+ }
+
fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>) -> PResult<'a, P<Expr>> {
let mut e = e0;
let lo = e.span.lo;
let mut hi;
loop {
// expr.f
- if try!(self.eat(&token::Dot) ){
+ if self.eat(&token::Dot) {
match self.token {
token::Ident(i, _) => {
- let dot = self.last_span.hi;
+ let dot_pos = self.last_span.hi;
hi = self.span.hi;
- try!(self.bump());
- let (_, tys, bindings) = if try!(self.eat(&token::ModSep) ){
- try!(self.expect_lt());
- try!(self.parse_generic_values_after_lt())
- } else {
- (Vec::new(), Vec::new(), Vec::new())
- };
-
- if !bindings.is_empty() {
- let last_span = self.last_span;
- self.span_err(last_span, "type bindings are only permitted on trait paths");
- }
+ self.bump();
- // expr.f() method call
- match self.token {
- token::OpenDelim(token::Paren) => {
- let mut es = try!(self.parse_unspanned_seq(
- &token::OpenDelim(token::Paren),
- &token::CloseDelim(token::Paren),
- seq_sep_trailing_allowed(token::Comma),
- |p| Ok(try!(p.parse_expr()))
- ));
- hi = self.last_span.hi;
-
- es.insert(0, e);
- let id = spanned(dot, hi, i);
- let nd = self.mk_method_call(id, tys, es);
- e = self.mk_expr(lo, hi, nd, None);
- }
- _ => {
- if !tys.is_empty() {
- let last_span = self.last_span;
- self.span_err(last_span,
- "field expressions may not \
- have type parameters");
- }
-
- let id = spanned(dot, hi, i);
- let field = self.mk_field(e, id);
- e = self.mk_expr(lo, hi, field, None);
- }
- }
+ e = try!(self.parse_dot_suffix(i, mk_sp(dot_pos, hi), e));
}
token::Literal(token::Integer(n), suf) => {
let sp = self.span;
let dot = self.last_span.hi;
hi = self.span.hi;
- try!(self.bump());
+ self.bump();
let index = n.as_str().parse::<usize>().ok();
match index {
}
}
token::Literal(token::Float(n), _suf) => {
- try!(self.bump());
+ self.bump();
let last_span = self.last_span;
let fstr = n.as_str();
let mut err = self.diagnostic().struct_span_err(last_span,
self.abort_if_errors();
}
- _ => return Err(self.unexpected())
+ _ => {
+ // FIXME Could factor this out into non_fatal_unexpected or something.
+ let actual = self.this_token_to_string();
+ self.span_err(self.span, &format!("unexpected token: `{}`", actual));
+
+ let dot_pos = self.last_span.hi;
+ e = try!(self.parse_dot_suffix(special_idents::invalid,
+ mk_sp(dot_pos, dot_pos),
+ e));
+ }
}
continue;
}
// expr[...]
// Could be either an index expression or a slicing expression.
token::OpenDelim(token::Bracket) => {
- try!(self.bump());
+ self.bump();
let ix = try!(self.parse_expr());
hi = self.span.hi;
try!(self.commit_expr_expecting(&*ix, token::CloseDelim(token::Bracket)));
let mut sp = self.span;
let (name, namep) = match self.token {
token::Dollar => {
- try!(self.bump());
+ self.bump();
if self.token == token::OpenDelim(token::Paren) {
let Spanned { node: seq, span: seq_span } = try!(self.parse_seq(
num_captures: name_num
})));
} else if self.token.is_keyword_allow_following_colon(keywords::Crate) {
- try!(self.bump());
+ self.bump();
return Ok(TokenTree::Token(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar)));
} else {
sp = mk_sp(sp.lo, self.span.hi);
}
}
token::SubstNt(name, namep) => {
- try!(self.bump());
+ self.bump();
(name, namep)
}
_ => unreachable!()
if self.token == token::Colon && self.look_ahead(1, |t| t.is_ident() &&
!t.is_strict_keyword() &&
!t.is_reserved_keyword()) {
- try!(self.bump());
+ self.bump();
sp = mk_sp(sp.lo, self.span.hi);
let kindp = match self.token { token::Ident(_, p) => p, _ => token::Plain };
let nt_kind = try!(self.parse_ident());
}
}
- pub fn check_unknown_macro_variable(&mut self) -> PResult<'a, ()> {
+ pub fn check_unknown_macro_variable(&mut self) {
if self.quote_depth == 0 {
match self.token {
token::SubstNt(name, _) =>
- return Err(self.fatal(&format!("unknown macro variable `{}`",
- name))),
+ self.fatal(&format!("unknown macro variable `{}`", name)).emit(),
_ => {}
}
}
- Ok(())
}
/// Parse an optional separator followed by a Kleene-style
fn parse_kleene_op<'a>(parser: &mut Parser<'a>) -> PResult<'a, Option<ast::KleeneOp>> {
match parser.token {
token::BinOp(token::Star) => {
- try!(parser.bump());
+ parser.bump();
Ok(Some(ast::ZeroOrMore))
},
token::BinOp(token::Plus) => {
- try!(parser.bump());
+ parser.bump();
Ok(Some(ast::OneOrMore))
},
_ => Ok(None)
None => {}
}
- let separator = try!(self.bump_and_get());
+ let separator = self.bump_and_get();
match try!(parse_kleene_op(self)) {
Some(zerok) => Ok((Some(separator), zerok)),
None => return Err(self.fatal("expected `*` or `+`"))
p.parse_unquoted()
}
_ => {
- Ok(TokenTree::Token(p.span, try!(p.bump_and_get())))
+ Ok(TokenTree::Token(p.span, p.bump_and_get()))
}
}
}
// Parse the open delimiter.
self.open_braces.push(self.span);
let open_span = self.span;
- try!(self.bump());
+ self.bump();
// Parse the token trees within the delimiters
let tts = try!(self.parse_seq_to_before_end(
// Parse the close delimiter.
let close_span = self.span;
- try!(self.bump());
+ self.bump();
self.open_braces.pop().unwrap();
// Expand to cover the entire delimited token tree
// Note: when adding new unary operators, don't forget to adjust Token::can_begin_expr()
let ex = match self.token {
token::Not => {
- try!(self.bump());
+ self.bump();
let e = try!(self.parse_prefix_expr(None));
hi = e.span.hi;
self.mk_unary(UnNot, e)
}
token::BinOp(token::Minus) => {
- try!(self.bump());
+ self.bump();
let e = try!(self.parse_prefix_expr(None));
hi = e.span.hi;
self.mk_unary(UnNeg, e)
}
token::BinOp(token::Star) => {
- try!(self.bump());
+ self.bump();
let e = try!(self.parse_prefix_expr(None));
hi = e.span.hi;
self.mk_unary(UnDeref, e)
ExprAddrOf(m, e)
}
token::Ident(..) if self.token.is_keyword(keywords::In) => {
- try!(self.bump());
+ self.bump();
let place = try!(self.parse_expr_res(
Restrictions::RESTRICTION_NO_STRUCT_LITERAL,
None,
ExprInPlace(place, blk_expr)
}
token::Ident(..) if self.token.is_keyword(keywords::Box) => {
- try!(self.bump());
+ self.bump();
let subexpression = try!(self.parse_prefix_expr(None));
hi = subexpression.span.hi;
ExprBox(subexpression)
if op.precedence() < min_prec {
break;
}
- try!(self.bump());
+ self.bump();
if op.is_comparison() {
self.check_no_chained_comparison(&*lhs, &op);
}
// We have 2 alternatives here: `x..y` and `x..` The other two variants are
// handled with `parse_prefix_range_expr` call above.
let rhs = if self.is_at_start_of_range_notation_rhs() {
- self.parse_assoc_expr_with(op.precedence() + 1,
- LhsExpr::NotYetParsed).ok()
+ let rhs = self.parse_assoc_expr_with(op.precedence() + 1,
+ LhsExpr::NotYetParsed);
+ match rhs {
+ Ok(e) => Some(e),
+ Err(mut e) => {
+ e.cancel();
+ None
+ }
+ }
} else {
None
};
let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs));
let lo = self.span.lo;
let mut hi = self.span.hi;
- try!(self.bump());
+ self.bump();
let opt_end = if self.is_at_start_of_range_notation_rhs() {
// RHS must be parsed with more associativity than DotDot.
let next_prec = AssocOp::from_token(&token::DotDot).unwrap().precedence() + 1;
let thn = try!(self.parse_block());
let mut els: Option<P<Expr>> = None;
let mut hi = thn.span.hi;
- if try!(self.eat_keyword(keywords::Else) ){
+ if self.eat_keyword(keywords::Else) {
let elexpr = try!(self.parse_else_expr());
hi = elexpr.span.hi;
els = Some(elexpr);
try!(self.expect(&token::Eq));
let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None));
let thn = try!(self.parse_block());
- let (hi, els) = if try!(self.eat_keyword(keywords::Else) ){
+ let (hi, els) = if self.eat_keyword(keywords::Else) {
let expr = try!(self.parse_else_expr());
(expr.span.hi, Some(expr))
} else {
// `else` token already eaten
pub fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
- if try!(self.eat_keyword(keywords::If) ){
+ if self.eat_keyword(keywords::If) {
return self.parse_if_expr(None);
} else {
let blk = try!(self.parse_block());
arms.push(try!(self.parse_arm()));
}
let hi = self.span.hi;
- try!(self.bump());
+ self.bump();
return Ok(self.mk_expr(lo, hi, ExprMatch(discriminant, arms), attrs));
}
let attrs = try!(self.parse_outer_attributes());
let pats = try!(self.parse_pats());
let mut guard = None;
- if try!(self.eat_keyword(keywords::If) ){
+ if self.eat_keyword(keywords::If) {
guard = Some(try!(self.parse_expr()));
}
try!(self.expect(&token::FatArrow));
if require_comma {
try!(self.commit_expr(&*expr, &[token::Comma], &[token::CloseDelim(token::Brace)]));
} else {
- try!(self.eat(&token::Comma));
+ self.eat(&token::Comma);
}
Ok(ast::Arm {
/// Parse the RHS of a local variable declaration (e.g. '= 14;')
fn parse_initializer(&mut self) -> PResult<'a, Option<P<Expr>>> {
if self.check(&token::Eq) {
- try!(self.bump());
+ self.bump();
Ok(Some(try!(self.parse_expr())))
} else {
Ok(None)
let mut pats = Vec::new();
loop {
pats.push(try!(self.parse_pat()));
- if self.check(&token::BinOp(token::Or)) { try!(self.bump());}
+ if self.check(&token::BinOp(token::Or)) { self.bump();}
else { return Ok(pats); }
};
}
if !self.check(&token::CloseDelim(token::Paren)) {
fields.push(try!(self.parse_pat()));
if self.look_ahead(1, |t| *t != token::CloseDelim(token::Paren)) {
- while try!(self.eat(&token::Comma)) &&
+ while self.eat(&token::Comma) &&
!self.check(&token::CloseDelim(token::Paren)) {
fields.push(try!(self.parse_pat()));
}
if before_slice {
if self.check(&token::DotDot) {
- try!(self.bump());
+ self.bump();
if self.check(&token::Comma) ||
self.check(&token::CloseDelim(token::Bracket)) {
let subpat = try!(self.parse_pat());
if before_slice && self.check(&token::DotDot) {
- try!(self.bump());
+ self.bump();
slice = Some(subpat);
before_slice = false;
} else if before_slice {
let hi;
if self.check(&token::DotDot) {
- try!(self.bump());
+ self.bump();
if self.token != token::CloseDelim(token::Brace) {
let token_str = self.this_token_to_string();
return Err(self.fatal(&format!("expected `{}`, found `{}`", "}",
let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
// Parsing a pattern of the form "fieldname: pat"
let fieldname = try!(self.parse_ident());
- try!(self.bump());
+ self.bump();
let pat = try!(self.parse_pat());
hi = pat.span.hi;
(pat, fieldname, false)
} else {
// Parsing a pattern of the form "(box) (ref) (mut) fieldname"
- let is_box = try!(self.eat_keyword(keywords::Box));
+ let is_box = self.eat_keyword(keywords::Box);
let boxed_span_lo = self.span.lo;
- let is_ref = try!(self.eat_keyword(keywords::Ref));
- let is_mut = try!(self.eat_keyword(keywords::Mut));
+ let is_ref = self.eat_keyword(keywords::Ref);
+ let is_mut = self.eat_keyword(keywords::Mut);
let fieldname = try!(self.parse_ident());
hi = self.last_span.hi;
fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
if self.is_path_start() {
let lo = self.span.lo;
- let (qself, path) = if try!(self.eat_lt()) {
+ let (qself, path) = if self.eat_lt() {
// Parse a qualified path
let (qself, path) =
try!(self.parse_qualified_path(NoTypesAllowed));
match self.token {
token::Underscore => {
// Parse _
- try!(self.bump());
+ self.bump();
pat = PatWild;
}
token::BinOp(token::And) | token::AndAnd => {
}
token::OpenDelim(token::Paren) => {
// Parse (pat,pat,pat,...) as tuple pattern
- try!(self.bump());
+ self.bump();
let fields = try!(self.parse_pat_tuple_elements());
try!(self.expect(&token::CloseDelim(token::Paren)));
pat = PatTup(fields);
}
token::OpenDelim(token::Bracket) => {
// Parse [pat,pat,...] as slice pattern
- try!(self.bump());
+ self.bump();
let (before, slice, after) = try!(self.parse_pat_vec_elements());
try!(self.expect(&token::CloseDelim(token::Bracket)));
pat = PatVec(before, slice, after);
}
_ => {
// At this point, token != _, &, &&, (, [
- if try!(self.eat_keyword(keywords::Mut)) {
+ if self.eat_keyword(keywords::Mut) {
// Parse mut ident @ pat
pat = try!(self.parse_pat_ident(BindingMode::ByValue(MutMutable)));
- } else if try!(self.eat_keyword(keywords::Ref)) {
+ } else if self.eat_keyword(keywords::Ref) {
// Parse ref ident @ pat / ref mut ident @ pat
let mutbl = try!(self.parse_mutability());
pat = try!(self.parse_pat_ident(BindingMode::ByRef(mutbl)));
- } else if try!(self.eat_keyword(keywords::Box)) {
+ } else if self.eat_keyword(keywords::Box) {
// Parse box pat
let subpat = try!(self.parse_pat());
pat = PatBox(subpat);
let ident = try!(self.parse_ident());
let ident_span = self.last_span;
let path = ident_to_path(ident_span, ident);
- try!(self.bump());
+ self.bump();
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()));
pat = try!(self.parse_pat_ident(BindingMode::ByValue(MutImmutable)));
}
} else {
- let (qself, path) = if try!(self.eat_lt()) {
+ let (qself, path) = if self.eat_lt() {
// Parse a qualified path
let (qself, path) =
try!(self.parse_qualified_path(NoTypesAllowed));
// Parse range
let hi = self.last_span.hi;
let begin = self.mk_expr(lo, hi, ExprPath(qself, path), None);
- try!(self.bump());
+ self.bump();
let end = try!(self.parse_pat_range_end());
pat = PatRange(begin, end);
}
return Err(self.fatal("unexpected `{` after qualified path"));
}
// Parse struct pattern
- try!(self.bump());
+ self.bump();
let (fields, etc) = try!(self.parse_pat_fields());
- try!(self.bump());
+ self.bump();
pat = PatStruct(path, fields, etc);
}
token::OpenDelim(token::Paren) => {
// Parse tuple struct or enum pattern
if self.look_ahead(1, |t| *t == token::DotDot) {
// This is a "top constructor only" pat
- try!(self.bump());
- try!(self.bump());
+ self.bump();
+ self.bump();
try!(self.expect(&token::CloseDelim(token::Paren)));
pat = PatEnum(path, None);
} else {
} else {
// Try to parse everything else as literal with optional minus
let begin = try!(self.parse_pat_literal_maybe_minus());
- if try!(self.eat(&token::DotDotDot)) {
+ if self.eat(&token::DotDotDot) {
let end = try!(self.parse_pat_range_end());
pat = PatRange(begin, end);
} else {
let ident = try!(self.parse_ident());
let last_span = self.last_span;
let name = codemap::Spanned{span: last_span, node: ident};
- let sub = if try!(self.eat(&token::At) ){
+ let sub = if self.eat(&token::At) {
Some(try!(self.parse_pat()))
} else {
None
let pat = try!(self.parse_pat());
let mut ty = None;
- if try!(self.eat(&token::Colon) ){
+ if self.eat(&token::Colon) {
ty = Some(try!(self.parse_ty_sum()));
}
let init = try!(self.parse_initializer());
// Potential trouble: if we allow macros with paths instead of
// idents, we'd need to look ahead past the whole path here...
let pth = try!(self.parse_path(NoTypesAllowed));
- try!(self.bump());
+ self.bump();
let id = match self.token {
token::OpenDelim(_) => token::special_idents::invalid, // no special identifier
//
// Require a semicolon or braces.
if style != MacStmtWithBraces {
- if !try!(self.eat(&token::Semi) ){
+ if !self.eat(&token::Semi) {
let last_span = self.last_span;
self.span_err(last_span,
"macros that expand to items must \
// Do not attempt to parse an expression if we're done here.
if self.token == token::Semi {
unused_attrs(&attrs, self);
- try!(self.bump());
+ self.bump();
return Ok(None);
}
let lo = self.span.lo;
- if !try!(self.eat(&token::OpenDelim(token::Brace)) ){
+ if !self.eat(&token::OpenDelim(token::Brace)) {
let sp = self.span;
let tok = self.this_token_to_string();
return Err(self.span_fatal_help(sp,
let mut stmts = vec![];
let mut expr = None;
- while !try!(self.eat(&token::CloseDelim(token::Brace))) {
+ while !self.eat(&token::CloseDelim(token::Brace)) {
let Spanned {node, span} = if let Some(s) = try!(self.parse_stmt_()) {
s
} else {
node: StmtMac(mac, MacStmtWithSemicolon, attrs),
span: mk_sp(span.lo, self.span.hi),
}));
- try!(self.bump());
+ self.bump();
}
_ => {
let e = self.mk_mac_expr(span.lo, span.hi,
node: StmtMac(m, MacStmtWithSemicolon, attrs),
span: mk_sp(span.lo, self.span.hi),
}));
- try!(self.bump());
+ self.bump();
}
token::CloseDelim(token::Brace) => {
// if a block ends in `m!(arg)` without
match self.token {
token::Semi => {
- try!(self.bump());
+ self.bump();
let span_with_semi = Span {
lo: span.lo,
hi: self.last_span.hi,
mode: BoundParsingMode)
-> PResult<'a, TyParamBounds>
{
- if !try!(self.eat(&token::Colon) ){
+ if !self.eat(&token::Colon) {
Ok(P::empty())
} else {
self.parse_ty_param_bounds(mode)
let mut result = vec!();
loop {
let question_span = self.span;
- let ate_question = try!(self.eat(&token::Question));
+ let ate_question = self.eat(&token::Question);
match self.token {
token::Lifetime(lifetime) => {
if ate_question {
span: self.span,
name: lifetime.name
}));
- try!(self.bump());
+ self.bump();
}
token::ModSep | token::Ident(..) => {
let poly_trait_ref = try!(self.parse_poly_trait_ref());
_ => break,
}
- if !try!(self.eat(&token::BinOp(token::Plus)) ){
+ if !self.eat(&token::BinOp(token::Plus)) {
break;
}
}
let bounds = try!(self.parse_colon_then_ty_param_bounds(BoundParsingMode::Modified));
let default = if self.check(&token::Eq) {
- try!(self.bump());
+ self.bump();
Some(try!(self.parse_ty_sum()))
} else {
None
pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
maybe_whole!(self, NtGenerics);
- if try!(self.eat(&token::Lt) ){
+ if self.eat(&token::Lt) {
let lifetime_defs = try!(self.parse_lifetime_defs());
let mut seen_default = false;
let ty_params = try!(self.parse_seq_to_gt(Some(token::Comma), |p| {
let mut err = self.diagnostic().struct_span_err(self.span, &msg);
let span_hi = self.span.hi;
- let span_hi = if self.parse_ty().is_ok() {
- self.span.hi
- } else {
- span_hi
+ let span_hi = match self.parse_ty() {
+ Ok(..) => self.span.hi,
+ Err(ref mut err) => {
+ err.cancel();
+ span_hi
+ }
};
let msg = format!("did you mean a single argument type &'a Type, \
try!(p.forbid_lifetime());
let lo = p.span.lo;
let ident = try!(p.parse_ident());
- let found_eq = try!(p.eat(&token::Eq));
+ let found_eq = p.eat(&token::Eq);
if !found_eq {
let span = p.span;
p.span_warn(span, "whoops, no =?");
predicates: Vec::new(),
};
- if !try!(self.eat_keyword(keywords::Where)) {
+ if !self.eat_keyword(keywords::Where) {
return Ok(where_clause);
}
let bounded_lifetime =
try!(self.parse_lifetime());
- try!(self.eat(&token::Colon));
+ self.eat(&token::Colon);
let bounds =
try!(self.parse_lifetimes(token::BinOp(token::Plus)));
}
_ => {
- let bound_lifetimes = if try!(self.eat_keyword(keywords::For) ){
+ let bound_lifetimes = if self.eat_keyword(keywords::For) {
// Higher ranked constraint.
try!(self.expect(&token::Lt));
let lifetime_defs = try!(self.parse_lifetime_defs());
let bounded_ty = try!(self.parse_ty());
- if try!(self.eat(&token::Colon) ){
+ if self.eat(&token::Colon) {
let bounds = try!(self.parse_ty_param_bounds(BoundParsingMode::Bare));
let hi = self.last_span.hi;
let span = mk_sp(lo, hi);
}));
parsed_something = true;
- } else if try!(self.eat(&token::Eq) ){
+ } else if self.eat(&token::Eq) {
// let ty = try!(self.parse_ty());
let hi = self.last_span.hi;
let span = mk_sp(lo, hi);
}
};
- if !try!(self.eat(&token::Comma) ){
+ if !self.eat(&token::Comma) {
break
}
}
seq_sep_trailing_allowed(token::Comma),
|p| {
if p.token == token::DotDotDot {
- try!(p.bump());
+ p.bump();
if allow_variadic {
if p.token != token::CloseDelim(token::Paren) {
let span = p.span;
fn expect_self_ident(&mut self) -> PResult<'a, ast::Ident> {
match self.token {
token::Ident(id, token::Plain) if id.name == special_idents::self_.name => {
- try!(self.bump());
+ self.bump();
Ok(id)
},
_ => {
fn expect_self_type_ident(&mut self) -> PResult<'a, ast::Ident> {
match self.token {
token::Ident(id, token::Plain) if id.name == special_idents::type_self.name => {
- try!(self.bump());
+ self.bump();
Ok(id)
},
_ => {
// We already know that the current token is `&`.
if this.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) {
- try!(this.bump());
+ this.bump();
Ok(SelfRegion(None, MutImmutable, try!(this.expect_self_ident())))
} else if this.look_ahead(1, |t| t.is_mutability()) &&
this.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) {
- try!(this.bump());
+ this.bump();
let mutability = try!(this.parse_mutability());
Ok(SelfRegion(None, mutability, try!(this.expect_self_ident())))
} else if this.look_ahead(1, |t| t.is_lifetime()) &&
this.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) {
- try!(this.bump());
+ this.bump();
let lifetime = try!(this.parse_lifetime());
Ok(SelfRegion(Some(lifetime), MutImmutable, try!(this.expect_self_ident())))
} else if this.look_ahead(1, |t| t.is_lifetime()) &&
this.look_ahead(2, |t| t.is_mutability()) &&
this.look_ahead(3, |t| t.is_keyword(keywords::SelfValue)) {
- try!(this.bump());
+ this.bump();
let lifetime = try!(this.parse_lifetime());
let mutability = try!(this.parse_mutability());
Ok(SelfRegion(Some(lifetime), mutability, try!(this.expect_self_ident())))
token::BinOp(token::Star) => {
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
// emitting cryptic "unexpected token" errors.
- try!(self.bump());
+ self.bump();
let _mutability = if self.token.is_mutability() {
try!(self.parse_mutability())
} else {
if self.is_self_ident() {
let span = self.span;
self.span_err(span, "cannot pass self by raw pointer");
- try!(self.bump());
+ self.bump();
}
// error case, making bogus self ident:
SelfValue(special_idents::self_)
// Determine whether this is the fully explicit form, `self:
// TYPE`.
- if try!(self.eat(&token::Colon) ){
+ if self.eat(&token::Colon) {
SelfExplicit(try!(self.parse_ty_sum()), self_ident)
} else {
SelfValue(self_ident)
// Determine whether this is the fully explicit form,
// `self: TYPE`.
- if try!(self.eat(&token::Colon) ){
+ if self.eat(&token::Colon) {
SelfExplicit(try!(self.parse_ty_sum()), self_ident)
} else {
SelfValue(self_ident)
// If we parsed a self type, expect a comma before the argument list.
match self.token {
token::Comma => {
- try!(self.bump());
+ self.bump();
let sep = seq_sep_trailing_allowed(token::Comma);
let mut fn_inputs = try!(self.parse_seq_to_before_end(
&token::CloseDelim(token::Paren),
// parse the |arg, arg| header on a lambda
fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> {
let inputs_captures = {
- if try!(self.eat(&token::OrOr) ){
+ if self.eat(&token::OrOr) {
Vec::new()
} else {
try!(self.expect(&token::BinOp(token::Or)));
seq_sep_trailing_allowed(token::Comma),
|p| p.parse_fn_block_arg()
));
- try!(self.bump());
+ self.bump();
args
}
};
/// - etc
pub fn parse_fn_front_matter(&mut self)
-> PResult<'a, (ast::Constness, ast::Unsafety, abi::Abi)> {
- let is_const_fn = try!(self.eat_keyword(keywords::Const));
+ let is_const_fn = self.eat_keyword(keywords::Const);
let unsafety = try!(self.parse_unsafety());
let (constness, unsafety, abi) = if is_const_fn {
(Constness::Const, unsafety, abi::Rust)
} else {
- let abi = if try!(self.eat_keyword(keywords::Extern)) {
+ let abi = if self.eat_keyword(keywords::Extern) {
try!(self.parse_opt_abi()).unwrap_or(abi::C)
} else {
abi::Rust
let mut attrs = try!(self.parse_outer_attributes());
let lo = self.span.lo;
let vis = try!(self.parse_visibility());
- let (name, node) = if try!(self.eat_keyword(keywords::Type)) {
+ let (name, node) = if self.eat_keyword(keywords::Type) {
let name = try!(self.parse_ident());
try!(self.expect(&token::Eq));
let typ = try!(self.parse_ty_sum());
let could_be_trait = self.token != token::OpenDelim(token::Paren);
let neg_span = self.span;
- let polarity = if try!(self.eat(&token::Not) ){
+ let polarity = if self.eat(&token::Not) {
ast::ImplPolarity::Negative
} else {
ast::ImplPolarity::Positive
let mut ty = try!(self.parse_ty_sum());
// Parse traits, if necessary.
- let opt_trait = if could_be_trait && try!(self.eat_keyword(keywords::For) ){
+ let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
// New-style trait. Reinterpret the type as a trait.
match ty.node {
TyPath(None, ref path) => {
None
};
- if opt_trait.is_some() && try!(self.eat(&token::DotDot) ){
+ if opt_trait.is_some() && self.eat(&token::DotDot) {
if generics.is_parameterized() {
self.span_err(impl_span, "default trait implementations are not \
allowed to have generics");
let attrs = try!(self.parse_inner_attributes());
let mut impl_items = vec![];
- while !try!(self.eat(&token::CloseDelim(token::Brace))) {
+ while !self.eat(&token::CloseDelim(token::Brace)) {
impl_items.push(try!(self.parse_impl_item()));
}
}
fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<ast::LifetimeDef>> {
- if try!(self.eat_keyword(keywords::For) ){
+ if self.eat_keyword(keywords::For) {
try!(self.expect(&token::Lt));
let lifetime_defs = try!(self.parse_lifetime_defs());
try!(self.expect_gt());
let vdata = if self.token.is_keyword(keywords::Where) {
generics.where_clause = try!(self.parse_where_clause());
- if try!(self.eat(&token::Semi)) {
+ if self.eat(&token::Semi) {
// If we see a: `struct Foo<T> where T: Copy;` style decl.
VariantData::Unit(ast::DUMMY_NODE_ID)
} else {
ast::DUMMY_NODE_ID)
}
// No `where` so: `struct Foo<T>;`
- } else if try!(self.eat(&token::Semi) ){
+ } else if self.eat(&token::Semi) {
VariantData::Unit(ast::DUMMY_NODE_ID)
// Record-style struct definition
} else if self.token == token::OpenDelim(token::Brace) {
parse_pub: ParsePub)
-> PResult<'a, Vec<StructField>> {
let mut fields = Vec::new();
- if try!(self.eat(&token::OpenDelim(token::Brace)) ){
+ if self.eat(&token::OpenDelim(token::Brace)) {
while self.token != token::CloseDelim(token::Brace) {
fields.push(try!(self.parse_struct_decl_field(parse_pub)));
}
- try!(self.bump());
+ self.bump();
} else {
let token_str = self.this_token_to_string();
return Err(self.fatal(&format!("expected `where`, or `{{` after struct \
let a_var = try!(self.parse_name_and_ty(vis, attrs));
match self.token {
token::Comma => {
- try!(self.bump());
+ self.bump();
}
token::CloseDelim(token::Brace) => {}
_ => {
let attrs = try!(self.parse_outer_attributes());
- if try!(self.eat_keyword(keywords::Pub) ){
+ if self.eat_keyword(keywords::Pub) {
if parse_pub == ParsePub::No {
let span = self.last_span;
self.span_err(span, "`pub` is not allowed here");
/// Parse visibility: PUB or nothing
fn parse_visibility(&mut self) -> PResult<'a, Visibility> {
- if try!(self.eat_keyword(keywords::Pub)) { Ok(Public) }
+ if self.eat_keyword(keywords::Pub) { Ok(Public) }
else { Ok(Inherited) }
}
items.push(item);
}
- if !try!(self.eat(term)) {
+ if !self.eat(term) {
let token_str = self.this_token_to_string();
return Err(self.fatal(&format!("expected item, found `{}`", token_str)));
}
let id_span = self.span;
let id = try!(self.parse_ident());
if self.check(&token::Semi) {
- try!(self.bump());
+ self.bump();
// This mod is in an external file. Let's go get it!
let (m, attrs) = try!(self.eval_src_mod(id, outer_attrs, id_span));
Ok((id, m, Some(attrs)))
fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: BytePos,
attrs: Vec<Attribute>) -> PResult<'a, P<ForeignItem>> {
try!(self.expect_keyword(keywords::Static));
- let mutbl = try!(self.eat_keyword(keywords::Mut));
+ let mutbl = self.eat_keyword(keywords::Mut);
let ident = try!(self.parse_ident());
try!(self.expect(&token::Colon));
all_nullary = false;
struct_def = VariantData::Tuple(try!(self.parse_tuple_struct_body(ParsePub::No)),
ast::DUMMY_NODE_ID);
- } else if try!(self.eat(&token::Eq) ){
+ } else if self.eat(&token::Eq) {
disr_expr = Some(try!(self.parse_expr()));
any_disr = disr_expr.as_ref().map(|expr| expr.span);
struct_def = VariantData::Unit(ast::DUMMY_NODE_ID);
};
variants.push(P(spanned(vlo, self.last_span.hi, vr)));
- if !try!(self.eat(&token::Comma)) { break; }
+ if !self.eat(&token::Comma) { break; }
}
try!(self.expect(&token::CloseDelim(token::Brace)));
match any_disr {
token::Literal(token::Str_(s), suf) | token::Literal(token::StrRaw(s, _), suf) => {
let sp = self.span;
self.expect_no_suffix(sp, "ABI spec", suf);
- try!(self.bump());
+ self.bump();
match abi::lookup(&s.as_str()) {
Some(abi) => Ok(Some(abi)),
None => {
};
match nt_item {
Some(mut item) => {
- try!(self.bump());
+ self.bump();
let mut attrs = attrs;
mem::swap(&mut item.attrs, &mut attrs);
item.attrs.extend(attrs);
let visibility = try!(self.parse_visibility());
- if try!(self.eat_keyword(keywords::Use) ){
+ if self.eat_keyword(keywords::Use) {
// USE ITEM
let item_ = ItemUse(try!(self.parse_view_path()));
try!(self.expect(&token::Semi));
return Ok(Some(item));
}
- if try!(self.eat_keyword(keywords::Extern)) {
- if try!(self.eat_keyword(keywords::Crate)) {
+ if self.eat_keyword(keywords::Extern) {
+ if self.eat_keyword(keywords::Crate) {
return Ok(Some(try!(self.parse_item_extern_crate(lo, visibility, attrs))));
}
let opt_abi = try!(self.parse_opt_abi());
- if try!(self.eat_keyword(keywords::Fn) ){
+ if self.eat_keyword(keywords::Fn) {
// EXTERN FUNCTION ITEM
let abi = opt_abi.unwrap_or(abi::C);
let (ident, item_, extra_attrs) =
return Ok(Some(try!(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs))));
}
- try!(self.expect_one_of(&[], &[]));
+ try!(self.unexpected());
}
- if try!(self.eat_keyword(keywords::Static) ){
+ if self.eat_keyword(keywords::Static) {
// STATIC ITEM
- let m = if try!(self.eat_keyword(keywords::Mut)) {MutMutable} else {MutImmutable};
+ let m = if self.eat_keyword(keywords::Mut) {MutMutable} else {MutImmutable};
let (ident, item_, extra_attrs) = try!(self.parse_item_const(Some(m)));
let last_span = self.last_span;
let item = self.mk_item(lo,
maybe_append(attrs, extra_attrs));
return Ok(Some(item));
}
- if try!(self.eat_keyword(keywords::Const) ){
+ if self.eat_keyword(keywords::Const) {
if self.check_keyword(keywords::Fn)
|| (self.check_keyword(keywords::Unsafe)
&& self.look_ahead(1, |t| t.is_keyword(keywords::Fn))) {
// CONST FUNCTION ITEM
- let unsafety = if try!(self.eat_keyword(keywords::Unsafe) ){
+ let unsafety = if self.eat_keyword(keywords::Unsafe) {
Unsafety::Unsafe
} else {
Unsafety::Normal
};
- try!(self.bump());
+ self.bump();
let (ident, item_, extra_attrs) =
try!(self.parse_item_fn(unsafety, Constness::Const, abi::Rust));
let last_span = self.last_span;
}
// CONST ITEM
- if try!(self.eat_keyword(keywords::Mut) ){
+ if self.eat_keyword(keywords::Mut) {
let last_span = self.last_span;
self.diagnostic().struct_span_err(last_span, "const globals cannot be mutable")
.fileline_help(last_span, "did you mean to declare a static?")
}
if self.check_keyword(keywords::Fn) {
// FUNCTION ITEM
- try!(self.bump());
+ self.bump();
let (ident, item_, extra_attrs) =
try!(self.parse_item_fn(Unsafety::Normal, Constness::NotConst, abi::Rust));
let last_span = self.last_span;
if self.check_keyword(keywords::Unsafe)
&& self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
// UNSAFE FUNCTION ITEM
- try!(self.bump());
- let abi = if try!(self.eat_keyword(keywords::Extern) ){
+ self.bump();
+ let abi = if self.eat_keyword(keywords::Extern) {
try!(self.parse_opt_abi()).unwrap_or(abi::C)
} else {
abi::Rust
maybe_append(attrs, extra_attrs));
return Ok(Some(item));
}
- if try!(self.eat_keyword(keywords::Mod) ){
+ if self.eat_keyword(keywords::Mod) {
// MODULE ITEM
let (ident, item_, extra_attrs) =
try!(self.parse_item_mod(&attrs[..]));
maybe_append(attrs, extra_attrs));
return Ok(Some(item));
}
- if try!(self.eat_keyword(keywords::Type) ){
+ if self.eat_keyword(keywords::Type) {
// TYPE ITEM
let (ident, item_, extra_attrs) = try!(self.parse_item_type());
let last_span = self.last_span;
maybe_append(attrs, extra_attrs));
return Ok(Some(item));
}
- if try!(self.eat_keyword(keywords::Enum) ){
+ if self.eat_keyword(keywords::Enum) {
// ENUM ITEM
let (ident, item_, extra_attrs) = try!(self.parse_item_enum());
let last_span = self.last_span;
maybe_append(attrs, extra_attrs));
return Ok(Some(item));
}
- if try!(self.eat_keyword(keywords::Trait) ){
+ if self.eat_keyword(keywords::Trait) {
// TRAIT ITEM
let (ident, item_, extra_attrs) =
try!(self.parse_item_trait(ast::Unsafety::Normal));
maybe_append(attrs, extra_attrs));
return Ok(Some(item));
}
- if try!(self.eat_keyword(keywords::Impl) ){
+ if self.eat_keyword(keywords::Impl) {
// IMPL ITEM
let (ident, item_, extra_attrs) = try!(self.parse_item_impl(ast::Unsafety::Normal));
let last_span = self.last_span;
maybe_append(attrs, extra_attrs));
return Ok(Some(item));
}
- if try!(self.eat_keyword(keywords::Struct) ){
+ if self.eat_keyword(keywords::Struct) {
// STRUCT ITEM
let (ident, item_, extra_attrs) = try!(self.parse_item_struct());
let last_span = self.last_span;
self.last_span.hi) };
if delim != token::Brace {
- if !try!(self.eat(&token::Semi) ){
+ if !self.eat(&token::Semi) {
let last_span = self.last_span;
self.span_err(last_span,
"macros that expand to items must either \
// Allow a leading :: because the paths are absolute either way.
// This occurs with "use $crate::..." in macros.
- try!(self.eat(&token::ModSep));
+ self.eat(&token::ModSep);
if self.check(&token::OpenDelim(token::Brace)) {
// use {foo,bar}
if let token::ModSep = self.token {
// foo::bar or foo::{a,b,c} or foo::*
while self.check(&token::ModSep) {
- try!(self.bump());
+ self.bump();
match self.token {
token::Ident(..) => {
// foo::bar::*
token::BinOp(token::Star) => {
- try!(self.bump());
+ self.bump();
let path = ast::Path {
span: mk_sp(lo, self.span.hi),
global: false,
}
fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
- if try!(self.eat_keyword(keywords::As)) {
+ if self.eat_keyword(keywords::As) {
self.parse_ident().map(Some)
} else {
Ok(None)
}
pub fn parse_optional_str(&mut self)
- -> PResult<'a, Option<(InternedString,
- ast::StrStyle,
- Option<ast::Name>)>> {
+ -> Option<(InternedString,
+ ast::StrStyle,
+ Option<ast::Name>)> {
let ret = match self.token {
token::Literal(token::Str_(s), suf) => {
(self.id_to_interned_str(ast::Ident::with_empty_ctxt(s)), ast::CookedStr, suf)
token::Literal(token::StrRaw(s, n), suf) => {
(self.id_to_interned_str(ast::Ident::with_empty_ctxt(s)), ast::RawStr(n), suf)
}
- _ => return Ok(None)
+ _ => return None
};
- try!(self.bump());
- Ok(Some(ret))
+ self.bump();
+ Some(ret)
}
pub fn parse_str(&mut self) -> PResult<'a, (InternedString, StrStyle)> {
- match try!(self.parse_optional_str()) {
+ match self.parse_optional_str() {
Some((s, style, suf)) => {
let sp = self.last_span;
self.expect_no_suffix(sp, "string literal", suf);