Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,29 +1140,27 @@ 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)]
#[diag("inclusive range with no end", code = E0586)]
#[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)]
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ impl<'a> Parser<'a> {
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
Expand All @@ -1243,14 +1243,10 @@ impl<'a> Parser<'a> {

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 }),
}
}

Expand Down
46 changes: 46 additions & 0 deletions tests/ui/parser/range-inclusive-suggestion-span.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#![crate_type = "rlib"]

// Suggestions for range patterns should not perform span manipulations that
// assume the range token is ASCII, because it could have been recovered from
// similar-looking Unicode characters.
//
// Regression test for <https://github.com/rust-lang/rust/issues/155799>.

// These dots are U+00B7 MIDDLE DOT, not an ASCII period.
fn dot_dot_dot() { ··· }
//~^ ERROR unknown start of token
//~| ERROR unknown start of token
//~| ERROR unknown start of token
//~| ERROR unexpected token: `...`
//~| ERROR inclusive range with no end

fn dot_dot_dot_eq() { ···= }
//~^ ERROR unknown start of token
//~| ERROR unknown start of token
//~| ERROR unknown start of token
//~| ERROR unexpected token: `...`
//~| ERROR unexpected `=` after inclusive range

fn dot_dot_dot_gt() { ···> }
//~^ ERROR unknown start of token
//~| ERROR unknown start of token
//~| ERROR unknown start of token
//~| ERROR unexpected token: `...`
//~| ERROR inclusive range with no end
//~| ERROR expected one of `;` or `}`, found `>`

fn dot_dot_eq() { ··= }
//~^ ERROR unknown start of token
//~| ERROR unknown start of token
//~| ERROR inclusive range with no end

fn dot_dot_eq_eq() { ··== }
//~^ ERROR unknown start of token
//~| ERROR unknown start of token
//~| ERROR unexpected `=` after inclusive range

fn dot_dot_eq_gt() { ··=> }
//~^ ERROR unknown start of token
//~| ERROR unknown start of token
//~| ERROR unexpected `>` after inclusive range
//~| ERROR expected one of `;` or `}`, found `>`
Loading
Loading