diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 49a2c414467..83bbfeb2805 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -721,6 +721,9 @@ parse_sugg_wrap_pattern_in_parens = wrap the pattern in parentheses parse_switch_mut_let_order = switch the order of `mut` and `let` +parse_switch_ref_box_order = switch the order of `ref` and `box` + .suggestion = swap them + parse_ternary_operator = Rust has no ternary operator .help = use an `if-else` expression instead diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 7ce348619c6..0a919240ce5 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -137,6 +137,14 @@ pub(crate) enum InvalidVariableDeclarationSub { UseLetNotVar(#[primary_span] Span), } +#[derive(Diagnostic)] +#[diag(parse_switch_ref_box_order)] +pub(crate) struct SwitchRefBoxOrder { + #[primary_span] + #[suggestion(applicability = "machine-applicable", code = "box ref")] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(parse_invalid_comparison_operator)] pub(crate) struct InvalidComparisonOperator { diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 15491cac56a..8f5f4459d64 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -5,8 +5,8 @@ use crate::errors::{ ExpectedCommaAfterPatternField, GenericArgsInPatRequireTurbofishSyntax, InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern, PatternOnWrongSideOfAt, RefMutOrderIncorrect, RemoveLet, RepeatedMutInPattern, - TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg, TrailingVertNotAllowed, - UnexpectedLifetimeInPattern, UnexpectedVertVertBeforeFunctionParam, + SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg, + TrailingVertNotAllowed, UnexpectedLifetimeInPattern, UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, }; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; @@ -374,6 +374,12 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(kw::Mut) { self.parse_pat_ident_mut(syntax_loc)? } else if self.eat_keyword(kw::Ref) { + if self.check_keyword(kw::Box) { + // Suggest `box ref` and quit parsing pattern to prevent series of + // misguided diagnostics from later stages of the compiler. + let span = self.prev_token.span.to(self.token.span); + return Err(self.sess.create_err(SwitchRefBoxOrder { span })); + } // Parse ref ident @ pat / ref mut ident @ pat let mutbl = self.parse_mutability(); self.parse_pat_ident(BindingAnnotation(ByRef::Yes, mutbl), syntax_loc)? diff --git a/tests/ui/pattern/pattern-bad-ref-box-order.fixed b/tests/ui/pattern/pattern-bad-ref-box-order.fixed new file mode 100644 index 00000000000..8825744a08b --- /dev/null +++ b/tests/ui/pattern/pattern-bad-ref-box-order.fixed @@ -0,0 +1,14 @@ +// run-rustfix + +#![feature(box_patterns)] +#![allow(dead_code)] + +fn foo(f: Option>) { + match f { + Some(box ref _i) => {}, + //~^ ERROR switch the order of `ref` and `box` + None => {} + } +} + +fn main() { } diff --git a/tests/ui/pattern/pattern-bad-ref-box-order.rs b/tests/ui/pattern/pattern-bad-ref-box-order.rs new file mode 100644 index 00000000000..f3fcf0ceacf --- /dev/null +++ b/tests/ui/pattern/pattern-bad-ref-box-order.rs @@ -0,0 +1,14 @@ +// run-rustfix + +#![feature(box_patterns)] +#![allow(dead_code)] + +fn foo(f: Option>) { + match f { + Some(ref box _i) => {}, + //~^ ERROR switch the order of `ref` and `box` + None => {} + } +} + +fn main() { } diff --git a/tests/ui/pattern/pattern-bad-ref-box-order.stderr b/tests/ui/pattern/pattern-bad-ref-box-order.stderr new file mode 100644 index 00000000000..a49f05c1028 --- /dev/null +++ b/tests/ui/pattern/pattern-bad-ref-box-order.stderr @@ -0,0 +1,8 @@ +error: switch the order of `ref` and `box` + --> $DIR/pattern-bad-ref-box-order.rs:8:14 + | +LL | Some(ref box _i) => {}, + | ^^^^^^^ help: swap them: `box ref` + +error: aborting due to 1 previous error +