about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-11-10 15:32:41 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-11-16 21:21:37 +0300
commitb85a3da421abad7d1936ec6e57e43c7b0ff10bd3 (patch)
treedec60e5f95768d7d15524a2e01defcb2f525ec50
parent00bc4496026a3168eed95e88c29f17dac2739d48 (diff)
downloadrust-b85a3da421abad7d1936ec6e57e43c7b0ff10bd3.tar.gz
rust-b85a3da421abad7d1936ec6e57e43c7b0ff10bd3.zip
parse: Support parsing optional literals
Revert weird renaming of the former `LitError::report`
-rw-r--r--src/librustc_parse/parser/expr.rs31
-rw-r--r--src/librustc_parse/parser/item.rs2
-rw-r--r--src/librustc_parse/parser/mod.rs15
3 files changed, 27 insertions, 21 deletions
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index dadb91f8b3c..df2f6822465 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -778,13 +778,12 @@ impl<'a> Parser<'a> {
 
         macro_rules! parse_lit {
             () => {
-                match self.parse_lit() {
-                    Ok(literal) => {
+                match self.parse_opt_lit() {
+                    Some(literal) => {
                         hi = self.prev_span;
                         ex = ExprKind::Lit(literal);
                     }
-                    Err(mut err) => {
-                        err.cancel();
+                    None => {
                         return Err(self.expected_expression_found());
                     }
                 }
@@ -1074,11 +1073,20 @@ impl<'a> Parser<'a> {
         self.maybe_recover_from_bad_qpath(expr, true)
     }
 
-    /// Matches `lit = true | false | token_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;
         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| {
                 if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix })
                         = next_token.kind {
@@ -1107,11 +1115,10 @@ impl<'a> Parser<'a> {
         match Lit::from_token(token) {
             Ok(lit) => {
                 self.bump();
-                Ok(lit)
+                Some(lit)
             }
             Err(LitError::NotLiteral) => {
-                let msg = format!("unexpected token: {}", self.this_token_descr());
-                Err(self.span_fatal(token.span, &msg))
+                None
             }
             Err(err) => {
                 let span = token.span;
@@ -1120,18 +1127,18 @@ impl<'a> Parser<'a> {
                     _ => unreachable!(),
                 };
                 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
                 // the error literal's symbol so they can be pretty-printed faithfully.
                 let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
                 let symbol = Symbol::intern(&suffixless_lit.to_string());
                 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.
         fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
             s.len() > 1
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 3b824dc939f..8e6df0fa4f3 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -105,7 +105,7 @@ impl<'a> Parser<'a> {
                 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) {
                 // EXTERN FUNCTION ITEM
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index 2b49091192c..7757e00020a 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -1214,21 +1214,20 @@ impl<'a> Parser<'a> {
     /// Parses `extern string_literal?`.
     fn parse_extern(&mut self) -> PResult<'a, Extern> {
         Ok(if self.eat_keyword(kw::Extern) {
-            Extern::from_abi(self.parse_opt_abi()?)
+            Extern::from_abi(self.parse_opt_abi())
         } else {
             Extern::None
         })
     }
 
     /// Parses a string literal as an ABI spec.
-    fn parse_opt_abi(&mut self) -> PResult<'a, Option<StrLit>> {
-        if self.token.can_begin_literal_or_bool() {
-            let ast::Lit { token: token::Lit { symbol, suffix, .. }, span, kind }
-                = self.parse_lit()?;
+    fn parse_opt_abi(&mut self) -> Option<StrLit> {
+        if let Some(ast::Lit { token: token::Lit { symbol, suffix, .. }, span, kind })
+                = self.parse_opt_lit() {
             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,
-                })),
+                }),
                 ast::LitKind::Err(_) => {}
                 _ => {
                     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.