Avoid improper spans when ... or ..= is recovered from non-ASCII

This avoids an ICE due to indexing into the middle of a multi-byte character.
This commit is contained in:
Zalathar
2026-04-26 21:02:20 +10:00
parent f107bb85a2
commit 9ceed255b5
4 changed files with 378 additions and 18 deletions
+4 -6
View File
@@ -1140,14 +1140,13 @@ pub(crate) struct InclusiveRangeMatchArrow {
#[primary_span]
pub arrow: Span,
#[label("this is parsed as an inclusive range `..=`")]
pub span: Span,
#[suggestion(
"add a space between the pattern and `=>`",
style = "verbose",
code = " ",
code = ".. =",
applicability = "machine-applicable"
)]
pub after_pat: Span,
pub span: Span,
}
#[derive(Diagnostic)]
@@ -1155,14 +1154,13 @@ pub(crate) struct InclusiveRangeMatchArrow {
#[note("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)")]
pub(crate) struct InclusiveRangeNoEnd {
#[primary_span]
pub span: Span,
#[suggestion(
"use `..` instead",
code = "",
code = "..",
applicability = "machine-applicable",
style = "verbose"
)]
pub suggestion: Span,
pub span: Span,
}
#[derive(Subdiagnostic)]
+4 -8
View File
@@ -1225,7 +1225,7 @@ fn parse_pat_range_begin_with(
pub(super) fn inclusive_range_with_incorrect_end(&mut self) -> ErrorGuaranteed {
let tok = &self.token;
let span = self.prev_token.span;
// If the user typed "..==" instead of "..=", we want to give them
// If the user typed "..==" or "...=" instead of "..=", we want to give them
// a specific error message telling them to use "..=".
// If they typed "..=>", suggest they use ".. =>".
// Otherwise, we assume that they meant to type a half open exclusive
@@ -1243,14 +1243,10 @@ pub(super) fn inclusive_range_with_incorrect_end(&mut self) -> ErrorGuaranteed {
self.dcx().emit_err(InclusiveRangeExtraEquals { span: span_with_eq })
}
token::Gt if no_space => {
let after_pat = span.with_hi(span.hi() - BytePos(1)).shrink_to_hi();
self.dcx().emit_err(InclusiveRangeMatchArrow { span, arrow: tok.span, after_pat })
token::Gt if self.prev_token.kind == token::DotDotEq && no_space => {
self.dcx().emit_err(InclusiveRangeMatchArrow { span, arrow: tok.span })
}
_ => self.dcx().emit_err(InclusiveRangeNoEnd {
span,
suggestion: span.with_lo(span.hi() - BytePos(1)),
}),
_ => self.dcx().emit_err(InclusiveRangeNoEnd { span }),
}
}