extract is_mistaken_not_ident_negation

This commit is contained in:
Mazdak Farrokhzad 2019-12-07 02:55:12 +01:00
parent 80eeefb05f
commit ada388b2b8

View File

@ -482,29 +482,8 @@ impl<'a> Parser<'a> {
(lo.to(span), self.mk_unary(UnOp::Deref, e))
}
token::BinOp(token::And) | token::AndAnd => self.parse_borrow_expr(lo)?,
token::Ident(..) if self.token.is_keyword(kw::Box) => {
self.bump();
let e = self.parse_prefix_expr(None);
let (span, e) = self.interpolated_or_expr_span(e)?;
let span = lo.to(span);
self.sess.gated_spans.gate(sym::box_syntax, span);
(span, ExprKind::Box(e))
}
token::Ident(..) if self.token.is_ident_named(sym::not) => {
// `not` is just an ordinary identifier in Rust-the-language,
// but as `rustc`-the-compiler, we can issue clever diagnostics
// for confused users who really want to say `!`
let token_cannot_continue_expr = |t: &Token| match t.kind {
// These tokens can start an expression after `!`, but
// can't continue an expression after an ident
token::Ident(name, is_raw) => token::ident_can_begin_expr(name, t.span, is_raw),
token::Literal(..) | token::Pound => true,
_ => t.is_whole_expr(),
};
if !self.look_ahead(1, token_cannot_continue_expr) {
return self.parse_dot_or_call_expr(Some(attrs));
}
token::Ident(..) if self.token.is_keyword(kw::Box) => self.parse_box_expr(lo)?,
token::Ident(..) if self.is_mistaken_not_ident_negation() => {
self.recover_not_expr(lo)?
}
_ => return self.parse_dot_or_call_expr(Some(attrs)),
@ -512,6 +491,28 @@ impl<'a> Parser<'a> {
return Ok(self.mk_expr(lo.to(hi), ex, attrs));
}
/// Parse `box expr`.
fn parse_box_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
self.bump();
let e = self.parse_prefix_expr(None);
let (span, e) = self.interpolated_or_expr_span(e)?;
let span = lo.to(span);
self.sess.gated_spans.gate(sym::box_syntax, span);
Ok((span, ExprKind::Box(e)))
}
fn is_mistaken_not_ident_negation(&self) -> bool {
let token_cannot_continue_expr = |t: &Token| match t.kind {
// These tokens can start an expression after `!`, but
// can't continue an expression after an ident
token::Ident(name, is_raw) => token::ident_can_begin_expr(name, t.span, is_raw),
token::Literal(..) | token::Pound => true,
_ => t.is_whole_expr(),
};
self.token.is_ident_named(sym::not) && self.look_ahead(1, token_cannot_continue_expr)
}
/// Recover on `not expr` in favor of `!expr`.
fn recover_not_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
self.bump();
// Emit the error ...