Description
Code
const x: () = |&'a
Current output
error: unexpected lifetime `'a` in pattern
--> fuzz_input.rs:1:19
|
1 | const x: () = |&'a
| ^^
|
error: expected parameter name, found `<eof>`
--> fuzz_input.rs:1:19
|
1 | const x: () = |&'a
| ^^ expected parameter name
error: aborting due to 2 previous errors
Desired output
error: unexpected lifetime `'a` in pattern
--> fuzz_input.rs:1:19
|
1 | const x: () = |&'a
| ^^
|
help: remove the lifetime
|
1 - const x: () = |&'a
1 + const x: () = |&
|
error: expected parameter name, found `<eof>`
--> fuzz_input.rs:1:21
|
1 | const x: () = |&'a
| ^ expected parameter name
error: aborting due to 2 previous errors
Rationale and extra context
This originates from this line in the bump
function:
if next.0.span.is_dummy() {
// Tweak the location for better diagnostics, but keep syntactic context intact.
let fallback_span = self.token.span; // <------ This line
next.0.span = fallback_span.with_ctxt(next.0.span.ctxt());
}
In the example input, the lifetime token is followed by an <eof>
token, which has the dummy span as specified in inlined_next
function. Thus the bump
function sets the span of the latter to that of the former, leading to an overlap. Then, in the construction site of the UnexpectedLifetimeInPattern
diagnostic in the parse_pat_deref
function, the suggestion span constructed from until
ing these spans becomes an empty span. Coincidentally, the suggestion code of this diagnostic is empty (removing the lifetime), causing the suggestion to be suppressed.
self.dcx().emit_err(UnexpectedLifetimeInPattern {
span: self.prev_token.span,
symbol: lifetime.name,
suggestion: self.prev_token.span.until(self.token.span), // <------ This line
});
In fact, the current behavior also causes a debug_assert!
to fail in the span_suggestion_with_style
function:
debug_assert!(
!(sp.is_empty() && suggestion.to_string().is_empty()),
"Span must not be empty and have no suggestion"
);
I have 2 possible suggestions for fixing the problem:
- Change the assignment of the span to be
self.token.span.shrink_to_hi()
, or; - Change the span of the returned
<eof>
token to be at the end position instead of the dummy span.
I have implemented and tested the first suggestion, and it works as expected. However, due to my lack of knowledge of the code base, I cannot figure out the other possible effects on the rest of the code, so I didn't open a pull request to fix this directly.
Other cases
Rust Version
rustc 1.85.0-nightly (9c707a8b7 2024-12-07)
binary: rustc
commit-hash: 9c707a8b769523bb6768bf58e74fa2c39cc24844
commit-date: 2024-12-07
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.5
Anything else?
No response