Repository navigation
sugg: point at the string literal missing the closing quote - #161478
vincenzopalazzo wants to merge 1 commit into
Conversation
Considering the following code
```rust
fn main() {
hello("world);
// a bunch of code was here
env("FLAGS", "-help")
}
```
the error generated before this commit from the compiler is
```
error[E0765]: unterminated double quote string
--> bug.rs:4:20
|
4 | env("FLAGS", "-help")
| ____________________^
5 | | }
| |__^
```
The compiler is not wrong here. The missing `"` on the line 2 makes
`"world);\n// a bunch of code was here\nenv("` a valid string literal,
so the quote that remains without a pair is really the one on the line
4. The problem is that the user has no way to know it, and in a real
file the two lines can be very far away from each other, in the issue
the compiler was pointing at the line 208 while the mistake was on the
line 180.
So this commit is keeping track of the first string literal that
contains an unescaped newline, and when the lexer finds an unterminated
string it points at it as a possible cause. A `\` at the end of the line
is a line continuation written on purpose, so these literals are skipped
and we do not blame them.
So the new error emitted by the compiler is
```
error[E0765]: unterminated double quote string
--> bug.rs:4:20
|
4 | env("FLAGS", "-help")
| ____________________^
5 | | }
| |__^
|
note: this string literal spans multiple lines; a missing closing `"` here could be the cause
--> bug.rs:2:7
|
2 | hello("world);
| _______^
3 | | // a bunch of code was here
4 | | env("FLAGS", "-help")
| |_____^
```
Fixes rust-lang#97001
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
|
The parser was modified, potentially altering the grammar of (stable) Rust cc @fmease |
|
r? @chenyukang rustbot has assigned @chenyukang. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
|
Did https://github.com/rust-lang/rust/blob/main/CLAUDE.md work in your case? |
|
@lqd looks like no? I will try to fix the guideline |
|
@lqd ok no looks like the claude.md is not working :/ I am fixing it now, sorry! Let me know if you want also that I will investigate the problem with the claude.md |
a413548 to
0fc7a19
Compare
|
Ok I fix it now, waiting for CI but in the meanwhile I am wondering if @chenyukang is fine to review the PR. Thanks |
| /// string. Remember the first such literal so we can point at it from that error. | ||
| fn maybe_record_multiline_str(&mut self, start: BytePos, end: BytePos) { | ||
| if self.first_multiline_str.is_some() { | ||
| return; |
There was a problem hiding this comment.
Once first_multiline_str is set, the early return prevents a later and more relevant multiline token from replacing it. Consequently, any legitimate multiline string earlier in the file causes the new note to blame unrelated code.
fn hello(_: &str) {}
fn env(_: &str, _: &str) {}
fn main() {
let _legitimate = "this string intentionally
spans two lines";
hello("world);
env("FLAGS", "-help")
}we should point to hello("world), but now we point to:
"this string intentionally
| _______________________^
6 | | spans two lines";
| |________________^| } | ||
| // Trim the delimiting quotes. | ||
| let mut chars = self.str_from_to(start + BytePos(1), end - BytePos(1)).chars(); | ||
| while let Some(c) = chars.next() { |
There was a problem hiding this comment.
I also have a little concern about performance here, since even there is no error, we need to carry the cost here for lexer.
|
@rustbot author |
Fixes #97001
Considering the following code
the error generated before this commit from the compiler is
The compiler is not wrong here. The missing
"on the line 2 makes"world);\n// a bunch of code was here\nenv("a valid string literal, so the quote that remains without a pair is really the one on the line 4. The problem is that the user has no way to know it, and in a real file the two lines can be very far away from each other, in the issue the compiler was pointing at the line 208 while the mistake was on the line 180.So this commit is keeping track of the first string literal that contains an unescaped newline, and when the lexer finds an unterminated string it points at it as a possible cause. A
\at the end of the line is a line continuation written on purpose, so these literals are skipped and we do not blame them.So the new error emitted by the compiler is
The heuristic is on the first literal with an unescaped newline, so in a file that already has a legit multi line string before the typo the note points to that one instead. This is why it is a
noteand not a suggestion, it is only to give a place where to start looking. Happy to move it to the nearest one before the error if you prefer.Tests added
unterminated-string-multiline-notefor the case of the issue andunterminated-string-line-continuationto be sure that a\at the end of the line is not reported.Dislaimer
AI helped me speed up test reproduction and analyse where in the compiler it's best to add this change. However, the changes are authored by me inside the Rust compiler. I am using AI to optimise my time because I am an old contributor in the compiler, but I do not find a lot of time these days to contribute, so AI is helping me to cut some time and go back to contributing because there are a few things that I would like to improve
Signed-off-by: Vincenzo Palazzo vincenzopalazzodev@gmail.com