Skip to content

Commit

Permalink
Rollup merge of #118359 - hkmatsumoto:suggest-box-ref, r=TaKO8Ki
Browse files Browse the repository at this point in the history
Suggest swapping the order of `ref` and `box`

It is not valid grammar to write `ref box <ident>` in patterns, but `box ref <ident>` is.
This patch adds a diagnostic to suggest swapping them, analogous to what we do for `mut let`.
  • Loading branch information
TaKO8Ki committed Nov 27, 2023
2 parents 465c4c9 + f4c2bde commit 215d84a
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 2 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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)?
Expand Down
14 changes: 14 additions & 0 deletions tests/ui/pattern/pattern-bad-ref-box-order.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// run-rustfix

#![feature(box_patterns)]
#![allow(dead_code)]

fn foo(f: Option<Box<i32>>) {
match f {
Some(box ref _i) => {},
//~^ ERROR switch the order of `ref` and `box`
None => {}
}
}

fn main() { }
14 changes: 14 additions & 0 deletions tests/ui/pattern/pattern-bad-ref-box-order.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// run-rustfix

#![feature(box_patterns)]
#![allow(dead_code)]

fn foo(f: Option<Box<i32>>) {
match f {
Some(ref box _i) => {},
//~^ ERROR switch the order of `ref` and `box`
None => {}
}
}

fn main() { }
8 changes: 8 additions & 0 deletions tests/ui/pattern/pattern-bad-ref-box-order.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 215d84a

Please sign in to comment.