Merge pull request #20425 from avrabe/feat/unterminated-string-hints

feat: hint at unterminated strings in unknown prefix errors
This commit is contained in:
Chayim Refael Friedman 2025-08-14 17:58:13 +00:00 committed by GitHub
commit 70fcdd59c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 1 deletions

View File

@ -149,6 +149,24 @@ impl<'a> Converter<'a> {
}
}
/// Check for likely unterminated string by analyzing STRING token content
fn has_likely_unterminated_string(&self) -> bool {
let Some(last_idx) = self.res.kind.len().checked_sub(1) else { return false };
for i in (0..=last_idx).rev().take(5) {
if self.res.kind[i] == STRING {
let start = self.res.start[i] as usize;
let end = self.res.start.get(i + 1).map(|&s| s as usize).unwrap_or(self.offset);
let content = &self.res.text[start..end];
if content.contains('(') && (content.contains("//") || content.contains(";\n")) {
return true;
}
}
}
false
}
fn finalize_with_eof(mut self) -> LexedStr<'a> {
self.res.push(EOF, self.offset);
self.res
@ -267,7 +285,17 @@ impl<'a> Converter<'a> {
rustc_lexer::TokenKind::Unknown => ERROR,
rustc_lexer::TokenKind::UnknownPrefix if token_text == "builtin" => IDENT,
rustc_lexer::TokenKind::UnknownPrefix => {
errors.push("unknown literal prefix".into());
let has_unterminated = self.has_likely_unterminated_string();
let error_msg = if has_unterminated {
format!(
"unknown literal prefix `{}` (note: check for unterminated string literal)",
token_text
)
} else {
"unknown literal prefix".to_owned()
};
errors.push(error_msg);
IDENT
}
rustc_lexer::TokenKind::Eof => EOF,

View File

@ -0,0 +1,15 @@
FN_KW "fn"
WHITESPACE " "
IDENT "main"
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
L_CURLY "{"
WHITESPACE "\n "
IDENT "hello"
L_PAREN "("
STRING "\"world);\n // a bunch of code was here\n env(\"FLAGS"
STRING "\", \""
MINUS "-"
IDENT "help" error: unknown literal prefix `help` (note: check for unterminated string literal)
STRING "\")\n}" error: Missing trailing `"` symbol to terminate the string literal

View File

@ -0,0 +1,5 @@
fn main() {
hello("world);
// a bunch of code was here
env("FLAGS", "-help")
}