diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_builtin_macros/src/format.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 2 |
2 files changed, 21 insertions, 2 deletions
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 373277f525d..48506148ed9 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -135,7 +135,26 @@ fn parse_args<'a>( return Err(ecx.struct_span_err(sp, "requires at least a format string argument")); } - let fmtstr = p.parse_expr()?; + let first_token = &p.token; + let fmtstr = match first_token.kind { + token::TokenKind::Literal(token::Lit { + kind: token::LitKind::Str | token::LitKind::StrRaw(_), + .. + }) => { + // If the first token is a string literal, then a format expression + // is constructed from it. + // + // This allows us to properly handle cases when the first comma + // after the format string is mistakenly replaced with any operator, + // which cause the expression parser to eat too much tokens. + p.parse_literal_maybe_minus()? + } + _ => { + // Otherwise, we fall back to the expression parser. + p.parse_expr()? + } + }; + let mut first = true; let mut named = false; diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index f022c628fe2..69d13b5cf53 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1480,7 +1480,7 @@ impl<'a> Parser<'a> { /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). /// Keep this in sync with `Token::can_begin_literal_maybe_minus`. - pub(super) fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> { + pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> { maybe_whole_expr!(self); let lo = self.token.span; |
