diff --git a/compiler/rustc_error_messages/locales/en-US/parse.ftl b/compiler/rustc_error_messages/locales/en-US/parse.ftl index 1728ef70cba0a..ee2d56570d8fb 100644 --- a/compiler/rustc_error_messages/locales/en-US/parse.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parse.ftl @@ -203,8 +203,9 @@ parse_inclusive_range_extra_equals = unexpected `=` after inclusive range .suggestion_remove_eq = use `..=` instead .note = inclusive ranges end with a single equals sign (`..=`) -parse_inclusive_range_match_arrow = unexpected `=>` after open range - .suggestion_add_space = add a space between the pattern and `=>` +parse_inclusive_range_match_arrow = unexpected `>` after inclusive range + .label = this is parsed as an inclusive range `..=` + .suggestion = add a space between the pattern and `=>` parse_inclusive_range_no_end = inclusive range with no end .suggestion_open_range = use `..` instead diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 054b41b478d60..083d7b5ac7515 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -667,13 +667,10 @@ pub(crate) struct InclusiveRangeExtraEquals { #[diag(parse_inclusive_range_match_arrow)] pub(crate) struct InclusiveRangeMatchArrow { #[primary_span] + pub arrow: Span, + #[label] pub span: Span, - #[suggestion( - suggestion_add_space, - style = "verbose", - code = " ", - applicability = "machine-applicable" - )] + #[suggestion(style = "verbose", code = " ", applicability = "machine-applicable")] pub after_pat: Span, } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 17d1e200b41aa..9eb551139492c 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2707,6 +2707,14 @@ impl<'a> Parser<'a> { ); err.emit(); this.bump(); + } else if matches!( + (&this.prev_token.kind, &this.token.kind), + (token::DotDotEq, token::Gt) + ) { + // `error_inclusive_range_match_arrow` handles cases like `0..=> {}`, + // so we supress the error here + err.delay_as_bug(); + this.bump(); } else { return Err(err); } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 912f7cc14f6cc..42d662ab20a96 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -777,7 +777,7 @@ impl<'a> Parser<'a> { self.error_inclusive_range_with_extra_equals(span_with_eq); } token::Gt if no_space => { - self.error_inclusive_range_match_arrow(span); + self.error_inclusive_range_match_arrow(span, tok.span); } _ => self.error_inclusive_range_with_no_end(span), } @@ -787,9 +787,9 @@ impl<'a> Parser<'a> { self.sess.emit_err(InclusiveRangeExtraEquals { span }); } - fn error_inclusive_range_match_arrow(&self, span: Span) { + fn error_inclusive_range_match_arrow(&self, span: Span, arrow: Span) { let after_pat = span.with_hi(span.hi() - rustc_span::BytePos(1)).shrink_to_hi(); - self.sess.emit_err(InclusiveRangeMatchArrow { span, after_pat }); + self.sess.emit_err(InclusiveRangeMatchArrow { span, arrow, after_pat }); } fn error_inclusive_range_with_no_end(&self, span: Span) { diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.rs index 7ba2b6d857cd0..30173b1b4be03 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.rs @@ -2,7 +2,8 @@ fn main() { let x = 42; match x { 0..=73 => {}, - 74..=> {}, //~ ERROR unexpected `=>` after open range - //~^ ERROR expected one of `=>`, `if`, or `|`, found `>` + 74..=> {}, + //~^ ERROR unexpected `>` after inclusive range + //~| NOTE this is parsed as an inclusive range `..=` } } diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.stderr index 9ba6d15113cd6..cb7f998df7a5b 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.stderr +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.stderr @@ -1,19 +1,15 @@ -error: unexpected `=>` after open range - --> $DIR/half-open-range-pats-inclusive-match-arrow.rs:5:11 +error: unexpected `>` after inclusive range + --> $DIR/half-open-range-pats-inclusive-match-arrow.rs:5:14 | LL | 74..=> {}, - | ^^^ + | ---^ + | | + | this is parsed as an inclusive range `..=` | help: add a space between the pattern and `=>` | LL | 74.. => {}, | + -error: expected one of `=>`, `if`, or `|`, found `>` - --> $DIR/half-open-range-pats-inclusive-match-arrow.rs:5:14 - | -LL | 74..=> {}, - | ^ expected one of `=>`, `if`, or `|` - -error: aborting due to 2 previous errors +error: aborting due to previous error