parse: Support parsing optional literals
Revert weird renaming of the former `LitError::report`
This commit is contained in:
parent
00bc449602
commit
b85a3da421
3 changed files with 27 additions and 21 deletions
|
@ -778,13 +778,12 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
macro_rules! parse_lit {
|
macro_rules! parse_lit {
|
||||||
() => {
|
() => {
|
||||||
match self.parse_lit() {
|
match self.parse_opt_lit() {
|
||||||
Ok(literal) => {
|
Some(literal) => {
|
||||||
hi = self.prev_span;
|
hi = self.prev_span;
|
||||||
ex = ExprKind::Lit(literal);
|
ex = ExprKind::Lit(literal);
|
||||||
}
|
}
|
||||||
Err(mut err) => {
|
None => {
|
||||||
err.cancel();
|
|
||||||
return Err(self.expected_expression_found());
|
return Err(self.expected_expression_found());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1074,11 +1073,20 @@ impl<'a> Parser<'a> {
|
||||||
self.maybe_recover_from_bad_qpath(expr, true)
|
self.maybe_recover_from_bad_qpath(expr, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Matches `lit = true | false | token_lit`.
|
|
||||||
pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
|
pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
|
||||||
|
self.parse_opt_lit().ok_or_else(|| {
|
||||||
|
let msg = format!("unexpected token: {}", self.this_token_descr());
|
||||||
|
self.span_fatal(self.token.span, &msg)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Matches `lit = true | false | token_lit`.
|
||||||
|
/// Returns `None` if the next token is not a literal.
|
||||||
|
pub(super) fn parse_opt_lit(&mut self) -> Option<Lit> {
|
||||||
let mut recovered = None;
|
let mut recovered = None;
|
||||||
if self.token == token::Dot {
|
if self.token == token::Dot {
|
||||||
// Attempt to recover `.4` as `0.4`.
|
// Attempt to recover `.4` as `0.4`. We don't currently have any syntax where
|
||||||
|
// dot would follow an optional literal, so we do this unconditionally.
|
||||||
recovered = self.look_ahead(1, |next_token| {
|
recovered = self.look_ahead(1, |next_token| {
|
||||||
if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix })
|
if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix })
|
||||||
= next_token.kind {
|
= next_token.kind {
|
||||||
|
@ -1107,11 +1115,10 @@ impl<'a> Parser<'a> {
|
||||||
match Lit::from_token(token) {
|
match Lit::from_token(token) {
|
||||||
Ok(lit) => {
|
Ok(lit) => {
|
||||||
self.bump();
|
self.bump();
|
||||||
Ok(lit)
|
Some(lit)
|
||||||
}
|
}
|
||||||
Err(LitError::NotLiteral) => {
|
Err(LitError::NotLiteral) => {
|
||||||
let msg = format!("unexpected token: {}", self.this_token_descr());
|
None
|
||||||
Err(self.span_fatal(token.span, &msg))
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let span = token.span;
|
let span = token.span;
|
||||||
|
@ -1120,18 +1127,18 @@ impl<'a> Parser<'a> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
self.bump();
|
self.bump();
|
||||||
self.error_literal_from_token(err, lit, span);
|
self.report_lit_error(err, lit, span);
|
||||||
// Pack possible quotes and prefixes from the original literal into
|
// Pack possible quotes and prefixes from the original literal into
|
||||||
// the error literal's symbol so they can be pretty-printed faithfully.
|
// the error literal's symbol so they can be pretty-printed faithfully.
|
||||||
let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
|
let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
|
||||||
let symbol = Symbol::intern(&suffixless_lit.to_string());
|
let symbol = Symbol::intern(&suffixless_lit.to_string());
|
||||||
let lit = token::Lit::new(token::Err, symbol, lit.suffix);
|
let lit = token::Lit::new(token::Err, symbol, lit.suffix);
|
||||||
Lit::from_lit_token(lit, span).map_err(|_| unreachable!())
|
Some(Lit::from_lit_token(lit, span).unwrap_or_else(|_| unreachable!()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_literal_from_token(&self, err: LitError, lit: token::Lit, span: Span) {
|
fn report_lit_error(&self, err: LitError, lit: token::Lit, span: Span) {
|
||||||
// Checks if `s` looks like i32 or u1234 etc.
|
// Checks if `s` looks like i32 or u1234 etc.
|
||||||
fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
|
fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
|
||||||
s.len() > 1
|
s.len() > 1
|
||||||
|
|
|
@ -105,7 +105,7 @@ impl<'a> Parser<'a> {
|
||||||
return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?));
|
return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?));
|
||||||
}
|
}
|
||||||
|
|
||||||
let abi = self.parse_opt_abi()?;
|
let abi = self.parse_opt_abi();
|
||||||
|
|
||||||
if self.eat_keyword(kw::Fn) {
|
if self.eat_keyword(kw::Fn) {
|
||||||
// EXTERN FUNCTION ITEM
|
// EXTERN FUNCTION ITEM
|
||||||
|
|
|
@ -1214,21 +1214,20 @@ impl<'a> Parser<'a> {
|
||||||
/// Parses `extern string_literal?`.
|
/// Parses `extern string_literal?`.
|
||||||
fn parse_extern(&mut self) -> PResult<'a, Extern> {
|
fn parse_extern(&mut self) -> PResult<'a, Extern> {
|
||||||
Ok(if self.eat_keyword(kw::Extern) {
|
Ok(if self.eat_keyword(kw::Extern) {
|
||||||
Extern::from_abi(self.parse_opt_abi()?)
|
Extern::from_abi(self.parse_opt_abi())
|
||||||
} else {
|
} else {
|
||||||
Extern::None
|
Extern::None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a string literal as an ABI spec.
|
/// Parses a string literal as an ABI spec.
|
||||||
fn parse_opt_abi(&mut self) -> PResult<'a, Option<StrLit>> {
|
fn parse_opt_abi(&mut self) -> Option<StrLit> {
|
||||||
if self.token.can_begin_literal_or_bool() {
|
if let Some(ast::Lit { token: token::Lit { symbol, suffix, .. }, span, kind })
|
||||||
let ast::Lit { token: token::Lit { symbol, suffix, .. }, span, kind }
|
= self.parse_opt_lit() {
|
||||||
= self.parse_lit()?;
|
|
||||||
match kind {
|
match kind {
|
||||||
ast::LitKind::Str(symbol_unescaped, style) => return Ok(Some(StrLit {
|
ast::LitKind::Str(symbol_unescaped, style) => return Some(StrLit {
|
||||||
style, symbol, suffix, span, symbol_unescaped,
|
style, symbol, suffix, span, symbol_unescaped,
|
||||||
})),
|
}),
|
||||||
ast::LitKind::Err(_) => {}
|
ast::LitKind::Err(_) => {}
|
||||||
_ => {
|
_ => {
|
||||||
self.struct_span_err(span, "non-string ABI literal")
|
self.struct_span_err(span, "non-string ABI literal")
|
||||||
|
@ -1242,7 +1241,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None)
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We are parsing `async fn`. If we are on Rust 2015, emit an error.
|
/// We are parsing `async fn`. If we are on Rust 2015, emit an error.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue