about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2022-12-05 14:39:56 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2022-12-05 15:04:33 +1100
commitd887615b4c83d856cd3e40000968c047f2ff4019 (patch)
tree5bc313564dcd33003f3087167ababad74b664189 /compiler/rustc_parse/src
parent4ae956f600e72d62a6b17d95705148442841cef0 (diff)
downloadrust-d887615b4c83d856cd3e40000968c047f2ff4019.tar.gz
rust-d887615b4c83d856cd3e40000968c047f2ff4019.zip
Parameterise `Parser::{recover_unclosed_char,handle_missing_lit}`.
These two methods both produce a `MetaItemLit`, and then some of the
call sites convert the `MetaItemLit` to a `token::Lit` with
`as_token_lit`.

This commit parameterises these two methods with a `mk_lit_char`
closure, which can be used to produce either `MetaItemLit` or
`token::Lit` directly as necessary.
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs57
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs22
2 files changed, 49 insertions, 30 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 1c773bea000..07f03e0d582 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1543,15 +1543,16 @@ impl<'a> Parser<'a> {
             && (matches!(self.token.kind, token::CloseDelim(_) | token::Comma)
                 || self.token.is_op())
         {
-            let lit = self.recover_unclosed_char(label_.ident, |self_| {
-                self_.sess.create_err(UnexpectedTokenAfterLabel {
-                    span: self_.token.span,
-                    remove_label: None,
-                    enclose_in_block: None,
-                })
-            });
+            let (lit, _) =
+                self.recover_unclosed_char(label_.ident, Parser::mk_token_lit_char, |self_| {
+                    self_.sess.create_err(UnexpectedTokenAfterLabel {
+                        span: self_.token.span,
+                        remove_label: None,
+                        enclose_in_block: None,
+                    })
+                });
             consume_colon = false;
-            Ok(self.mk_expr(lo, ExprKind::Lit(lit.as_token_lit())))
+            Ok(self.mk_expr(lo, ExprKind::Lit(lit)))
         } else if !ate_colon
             && (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt))
         {
@@ -1626,12 +1627,13 @@ impl<'a> Parser<'a> {
         Ok(expr)
     }
 
-    /// Emit an error when a char is parsed as a lifetime because of a missing quote
-    pub(super) fn recover_unclosed_char(
+    /// Emit an error when a char is parsed as a lifetime because of a missing quote.
+    pub(super) fn recover_unclosed_char<L>(
         &self,
         lifetime: Ident,
+        mk_lit_char: impl FnOnce(Symbol, Span) -> L,
         err: impl FnOnce(&Self) -> DiagnosticBuilder<'a, ErrorGuaranteed>,
-    ) -> ast::MetaItemLit {
+    ) -> L {
         if let Some(mut diag) =
             self.sess.span_diagnostic.steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar)
         {
@@ -1653,12 +1655,7 @@ impl<'a> Parser<'a> {
                 .emit();
         }
         let name = lifetime.without_first_quote().name;
-        ast::MetaItemLit {
-            symbol: name,
-            suffix: None,
-            kind: ast::LitKind::Char(name.as_str().chars().next().unwrap_or('_')),
-            span: lifetime.span,
-        }
+        mk_lit_char(name, lifetime.span)
     }
 
     /// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
@@ -1785,7 +1782,23 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn handle_missing_lit(&mut self) -> PResult<'a, MetaItemLit> {
+    pub(crate) fn mk_token_lit_char(name: Symbol, span: Span) -> (token::Lit, Span) {
+        (token::Lit { symbol: name, suffix: None, kind: token::Char }, span)
+    }
+
+    fn mk_meta_item_lit_char(name: Symbol, span: Span) -> MetaItemLit {
+        ast::MetaItemLit {
+            symbol: name,
+            suffix: None,
+            kind: ast::LitKind::Char(name.as_str().chars().next().unwrap_or('_')),
+            span,
+        }
+    }
+
+    fn handle_missing_lit<L>(
+        &mut self,
+        mk_lit_char: impl FnOnce(Symbol, Span) -> L,
+    ) -> PResult<'a, L> {
         if let token::Interpolated(inner) = &self.token.kind {
             let expr = match inner.as_ref() {
                 token::NtExpr(expr) => Some(expr),
@@ -1809,7 +1822,7 @@ impl<'a> Parser<'a> {
         // On an error path, eagerly consider a lifetime to be an unclosed character lit
         if self.token.is_lifetime() {
             let lt = self.expect_lifetime();
-            Ok(self.recover_unclosed_char(lt.ident, err))
+            Ok(self.recover_unclosed_char(lt.ident, mk_lit_char, err))
         } else {
             Err(err(self))
         }
@@ -1818,11 +1831,13 @@ impl<'a> Parser<'a> {
     pub(super) fn parse_token_lit(&mut self) -> PResult<'a, (token::Lit, Span)> {
         self.parse_opt_token_lit()
             .ok_or(())
-            .or_else(|()| self.handle_missing_lit().map(|lit| (lit.as_token_lit(), lit.span)))
+            .or_else(|()| self.handle_missing_lit(Parser::mk_token_lit_char))
     }
 
     pub(super) fn parse_meta_item_lit(&mut self) -> PResult<'a, MetaItemLit> {
-        self.parse_opt_meta_item_lit().ok_or(()).or_else(|()| self.handle_missing_lit())
+        self.parse_opt_meta_item_lit()
+            .ok_or(())
+            .or_else(|()| self.handle_missing_lit(Parser::mk_meta_item_lit_char))
     }
 
     fn recover_after_dot(&mut self) -> Option<Token> {
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index b5147158f70..a1981e11477 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -411,16 +411,20 @@ impl<'a> Parser<'a> {
         {
             // Recover a `'a` as a `'a'` literal
             let lt = self.expect_lifetime();
-            let lit = self.recover_unclosed_char(lt.ident, |self_| {
-                let expected = expected.unwrap_or("pattern");
-                let msg =
-                    format!("expected {}, found {}", expected, super::token_descr(&self_.token));
+            let (lit, _) =
+                self.recover_unclosed_char(lt.ident, Parser::mk_token_lit_char, |self_| {
+                    let expected = expected.unwrap_or("pattern");
+                    let msg = format!(
+                        "expected {}, found {}",
+                        expected,
+                        super::token_descr(&self_.token)
+                    );
 
-                let mut err = self_.struct_span_err(self_.token.span, &msg);
-                err.span_label(self_.token.span, format!("expected {}", expected));
-                err
-            });
-            PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit.as_token_lit())))
+                    let mut err = self_.struct_span_err(self_.token.span, &msg);
+                    err.span_label(self_.token.span, format!("expected {}", expected));
+                    err
+                });
+            PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit)))
         } else {
             // Try to parse everything else as literal with optional minus
             match self.parse_literal_maybe_minus() {