Skip to content

Commit d887615

Browse files
committed
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.
1 parent 4ae956f commit d887615

File tree

2 files changed

+49
-30
lines changed

2 files changed

+49
-30
lines changed

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,15 +1543,16 @@ impl<'a> Parser<'a> {
15431543
&& (matches!(self.token.kind, token::CloseDelim(_) | token::Comma)
15441544
|| self.token.is_op())
15451545
{
1546-
let lit = self.recover_unclosed_char(label_.ident, |self_| {
1547-
self_.sess.create_err(UnexpectedTokenAfterLabel {
1548-
span: self_.token.span,
1549-
remove_label: None,
1550-
enclose_in_block: None,
1551-
})
1552-
});
1546+
let (lit, _) =
1547+
self.recover_unclosed_char(label_.ident, Parser::mk_token_lit_char, |self_| {
1548+
self_.sess.create_err(UnexpectedTokenAfterLabel {
1549+
span: self_.token.span,
1550+
remove_label: None,
1551+
enclose_in_block: None,
1552+
})
1553+
});
15531554
consume_colon = false;
1554-
Ok(self.mk_expr(lo, ExprKind::Lit(lit.as_token_lit())))
1555+
Ok(self.mk_expr(lo, ExprKind::Lit(lit)))
15551556
} else if !ate_colon
15561557
&& (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt))
15571558
{
@@ -1626,12 +1627,13 @@ impl<'a> Parser<'a> {
16261627
Ok(expr)
16271628
}
16281629

1629-
/// Emit an error when a char is parsed as a lifetime because of a missing quote
1630-
pub(super) fn recover_unclosed_char(
1630+
/// Emit an error when a char is parsed as a lifetime because of a missing quote.
1631+
pub(super) fn recover_unclosed_char<L>(
16311632
&self,
16321633
lifetime: Ident,
1634+
mk_lit_char: impl FnOnce(Symbol, Span) -> L,
16331635
err: impl FnOnce(&Self) -> DiagnosticBuilder<'a, ErrorGuaranteed>,
1634-
) -> ast::MetaItemLit {
1636+
) -> L {
16351637
if let Some(mut diag) =
16361638
self.sess.span_diagnostic.steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar)
16371639
{
@@ -1653,12 +1655,7 @@ impl<'a> Parser<'a> {
16531655
.emit();
16541656
}
16551657
let name = lifetime.without_first_quote().name;
1656-
ast::MetaItemLit {
1657-
symbol: name,
1658-
suffix: None,
1659-
kind: ast::LitKind::Char(name.as_str().chars().next().unwrap_or('_')),
1660-
span: lifetime.span,
1661-
}
1658+
mk_lit_char(name, lifetime.span)
16621659
}
16631660

16641661
/// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
@@ -1785,7 +1782,23 @@ impl<'a> Parser<'a> {
17851782
}
17861783
}
17871784

1788-
fn handle_missing_lit(&mut self) -> PResult<'a, MetaItemLit> {
1785+
pub(crate) fn mk_token_lit_char(name: Symbol, span: Span) -> (token::Lit, Span) {
1786+
(token::Lit { symbol: name, suffix: None, kind: token::Char }, span)
1787+
}
1788+
1789+
fn mk_meta_item_lit_char(name: Symbol, span: Span) -> MetaItemLit {
1790+
ast::MetaItemLit {
1791+
symbol: name,
1792+
suffix: None,
1793+
kind: ast::LitKind::Char(name.as_str().chars().next().unwrap_or('_')),
1794+
span,
1795+
}
1796+
}
1797+
1798+
fn handle_missing_lit<L>(
1799+
&mut self,
1800+
mk_lit_char: impl FnOnce(Symbol, Span) -> L,
1801+
) -> PResult<'a, L> {
17891802
if let token::Interpolated(inner) = &self.token.kind {
17901803
let expr = match inner.as_ref() {
17911804
token::NtExpr(expr) => Some(expr),
@@ -1809,7 +1822,7 @@ impl<'a> Parser<'a> {
18091822
// On an error path, eagerly consider a lifetime to be an unclosed character lit
18101823
if self.token.is_lifetime() {
18111824
let lt = self.expect_lifetime();
1812-
Ok(self.recover_unclosed_char(lt.ident, err))
1825+
Ok(self.recover_unclosed_char(lt.ident, mk_lit_char, err))
18131826
} else {
18141827
Err(err(self))
18151828
}
@@ -1818,11 +1831,13 @@ impl<'a> Parser<'a> {
18181831
pub(super) fn parse_token_lit(&mut self) -> PResult<'a, (token::Lit, Span)> {
18191832
self.parse_opt_token_lit()
18201833
.ok_or(())
1821-
.or_else(|()| self.handle_missing_lit().map(|lit| (lit.as_token_lit(), lit.span)))
1834+
.or_else(|()| self.handle_missing_lit(Parser::mk_token_lit_char))
18221835
}
18231836

18241837
pub(super) fn parse_meta_item_lit(&mut self) -> PResult<'a, MetaItemLit> {
1825-
self.parse_opt_meta_item_lit().ok_or(()).or_else(|()| self.handle_missing_lit())
1838+
self.parse_opt_meta_item_lit()
1839+
.ok_or(())
1840+
.or_else(|()| self.handle_missing_lit(Parser::mk_meta_item_lit_char))
18261841
}
18271842

18281843
fn recover_after_dot(&mut self) -> Option<Token> {

compiler/rustc_parse/src/parser/pat.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -411,16 +411,20 @@ impl<'a> Parser<'a> {
411411
{
412412
// Recover a `'a` as a `'a'` literal
413413
let lt = self.expect_lifetime();
414-
let lit = self.recover_unclosed_char(lt.ident, |self_| {
415-
let expected = expected.unwrap_or("pattern");
416-
let msg =
417-
format!("expected {}, found {}", expected, super::token_descr(&self_.token));
414+
let (lit, _) =
415+
self.recover_unclosed_char(lt.ident, Parser::mk_token_lit_char, |self_| {
416+
let expected = expected.unwrap_or("pattern");
417+
let msg = format!(
418+
"expected {}, found {}",
419+
expected,
420+
super::token_descr(&self_.token)
421+
);
418422

419-
let mut err = self_.struct_span_err(self_.token.span, &msg);
420-
err.span_label(self_.token.span, format!("expected {}", expected));
421-
err
422-
});
423-
PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit.as_token_lit())))
423+
let mut err = self_.struct_span_err(self_.token.span, &msg);
424+
err.span_label(self_.token.span, format!("expected {}", expected));
425+
err
426+
});
427+
PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit)))
424428
} else {
425429
// Try to parse everything else as literal with optional minus
426430
match self.parse_literal_maybe_minus() {

0 commit comments

Comments
 (0)