feat: hint at unterminated strings in unknown prefix errors

When encountering 'unknown literal prefix' errors, check for unbalanced
quotes in recent code and suggest checking for unterminated string literals.
This commit is contained in:
Ralf Anton Beier 2025-08-11 06:16:34 +02:00
parent 92ba1cc30c
commit e7c3fe1978
No known key found for this signature in database
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")
}