mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-07 12:33:14 +00:00
Auto merge of #123877 - ShE3py:expr-in-pats-2, r=fmease
Further improve diagnostics for expressions in pattern position Follow-up of #118625, see #121697. ```rs fn main() { match 'b' { y.0.0.1.z().f()? as u32 => {}, } } ``` Before: ``` error: expected one of `=>`, ``@`,` `if`, or `|`, found `.` --> src/main.rs:3:10 | 3 | y.0.0.1.z().f()? as u32 => {}, | ^ expected one of `=>`, ``@`,` `if`, or `|` ``` After: ``` error: expected a pattern, found an expression --> src/main.rs:3:9 | 3 | y.0.0.1.z().f()? as u32 => {}, | ^^^^^^^^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns | help: consider moving the expression to a match arm guard | 3 | val if val == y.0.0.1.z().f()? as u32 => {}, | ~~~ +++++++++++++++++++++++++++++++++ help: consider extracting the expression into a `const` | 2 + const VAL: /* Type */ = y.0.0.1.z().f()? as u32; 3 ~ match 'b' { 4 ~ VAL => {}, | help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`) | 3 | const { y.0.0.1.z().f()? as u32 } => {}, | +++++++ + ``` --- r? fmease `@rustbot` label +A-diagnostics +A-parser +A-patterns +C-enhancement
This commit is contained in:
commit
df7f77811c
@ -571,6 +571,8 @@ pub enum StashKey {
|
||||
/// Query cycle detected, stashing in favor of a better error.
|
||||
Cycle,
|
||||
UndeterminedMacroResolution,
|
||||
/// Used by `Parser::maybe_recover_trailing_expr`
|
||||
ExprInPat,
|
||||
}
|
||||
|
||||
fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
|
||||
|
@ -803,15 +803,17 @@ parse_unexpected_expr_in_pat =
|
||||
expected {$is_bound ->
|
||||
[true] a pattern range bound
|
||||
*[false] a pattern
|
||||
}, found {$is_method_call ->
|
||||
[true] a method call
|
||||
*[false] an expression
|
||||
}
|
||||
}, found an expression
|
||||
|
||||
.label = {$is_method_call ->
|
||||
[true] method calls
|
||||
*[false] arbitrary expressions
|
||||
} are not allowed in patterns
|
||||
.label = arbitrary expressions are not allowed in patterns
|
||||
|
||||
parse_unexpected_expr_in_pat_const_sugg = consider extracting the expression into a `const`
|
||||
|
||||
parse_unexpected_expr_in_pat_create_guard_sugg = consider moving the expression to a match arm guard
|
||||
|
||||
parse_unexpected_expr_in_pat_inline_const_sugg = consider wrapping the expression in an inline `const` (requires `{"#"}![feature(inline_const_pat)]`)
|
||||
|
||||
parse_unexpected_expr_in_pat_update_guard_sugg = consider moving the expression to the match arm guard
|
||||
|
||||
parse_unexpected_if_with_if = unexpected `if` in the condition expression
|
||||
.suggestion = remove the `if`
|
||||
|
@ -1,3 +1,5 @@
|
||||
// ignore-tidy-filelength
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use rustc_ast::token::Token;
|
||||
@ -2592,13 +2594,86 @@ pub(crate) struct ExpectedCommaAfterPatternField {
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_unexpected_expr_in_pat)]
|
||||
pub(crate) struct UnexpectedExpressionInPattern {
|
||||
/// The unexpected expr's span.
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
/// Was a `RangePatternBound` expected?
|
||||
pub is_bound: bool,
|
||||
/// Was the unexpected expression a `MethodCallExpression`?
|
||||
pub is_method_call: bool,
|
||||
/// The unexpected expr's precedence (used in match arm guard suggestions).
|
||||
pub expr_precedence: i8,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum UnexpectedExpressionInPatternSugg {
|
||||
#[multipart_suggestion(
|
||||
parse_unexpected_expr_in_pat_create_guard_sugg,
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
CreateGuard {
|
||||
/// Where to put the suggested identifier.
|
||||
#[suggestion_part(code = "{ident}")]
|
||||
ident_span: Span,
|
||||
/// Where to put the match arm.
|
||||
#[suggestion_part(code = " if {ident} == {expr}")]
|
||||
pat_hi: Span,
|
||||
/// The suggested identifier.
|
||||
ident: String,
|
||||
/// The unexpected expression.
|
||||
expr: String,
|
||||
},
|
||||
|
||||
#[multipart_suggestion(
|
||||
parse_unexpected_expr_in_pat_update_guard_sugg,
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
UpdateGuard {
|
||||
/// Where to put the suggested identifier.
|
||||
#[suggestion_part(code = "{ident}")]
|
||||
ident_span: Span,
|
||||
/// The beginning of the match arm guard's expression (insert a `(` if `Some`).
|
||||
#[suggestion_part(code = "(")]
|
||||
guard_lo: Option<Span>,
|
||||
/// The end of the match arm guard's expression.
|
||||
#[suggestion_part(code = "{guard_hi_paren} && {ident} == {expr}")]
|
||||
guard_hi: Span,
|
||||
/// Either `")"` or `""`.
|
||||
guard_hi_paren: &'static str,
|
||||
/// The suggested identifier.
|
||||
ident: String,
|
||||
/// The unexpected expression.
|
||||
expr: String,
|
||||
},
|
||||
|
||||
#[multipart_suggestion(
|
||||
parse_unexpected_expr_in_pat_const_sugg,
|
||||
applicability = "has-placeholders"
|
||||
)]
|
||||
Const {
|
||||
/// Where to put the extracted constant declaration.
|
||||
#[suggestion_part(code = "{indentation}const {ident}: /* Type */ = {expr};\n")]
|
||||
stmt_lo: Span,
|
||||
/// Where to put the suggested identifier.
|
||||
#[suggestion_part(code = "{ident}")]
|
||||
ident_span: Span,
|
||||
/// The suggested identifier.
|
||||
ident: String,
|
||||
/// The unexpected expression.
|
||||
expr: String,
|
||||
/// The statement's block's indentation.
|
||||
indentation: String,
|
||||
},
|
||||
|
||||
#[multipart_suggestion(
|
||||
parse_unexpected_expr_in_pat_inline_const_sugg,
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
InlineConst {
|
||||
#[suggestion_part(code = "const {{ ")]
|
||||
start_span: Span,
|
||||
#[suggestion_part(code = " }}")]
|
||||
end_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -41,7 +41,7 @@ use super::{
|
||||
use crate::{errors, maybe_recover_from_interpolated_ty_qpath};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum DestructuredFloat {
|
||||
pub(super) enum DestructuredFloat {
|
||||
/// 1e2
|
||||
Single(Symbol, Span),
|
||||
/// 1.
|
||||
@ -1041,7 +1041,7 @@ impl<'a> Parser<'a> {
|
||||
// support pushing "future tokens" (would be also helpful to `break_and_eat`), or
|
||||
// we should break everything including floats into more basic proc-macro style
|
||||
// tokens in the lexer (probably preferable).
|
||||
fn break_up_float(&self, float: Symbol, span: Span) -> DestructuredFloat {
|
||||
pub(super) fn break_up_float(&self, float: Symbol, span: Span) -> DestructuredFloat {
|
||||
#[derive(Debug)]
|
||||
enum FloatComponent {
|
||||
IdentLike(String),
|
||||
|
@ -1,12 +1,14 @@
|
||||
use rustc_ast::mut_visit::{walk_pat, MutVisitor};
|
||||
use rustc_ast::mut_visit::{self, MutVisitor};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token};
|
||||
use rustc_ast::visit::{self, Visitor};
|
||||
use rustc_ast::{
|
||||
self as ast, AttrVec, BindingMode, ByRef, Expr, ExprKind, MacCall, Mutability, Pat, PatField,
|
||||
PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
|
||||
self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, ExprPrecedence,
|
||||
LocalKind, MacCall, Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd,
|
||||
RangeSyntax, Stmt, StmtKind,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{Applicability, Diag, PResult};
|
||||
use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey};
|
||||
use rustc_session::errors::ExprParenthesesNeeded;
|
||||
use rustc_span::source_map::{respan, Spanned};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
@ -21,11 +23,11 @@ use crate::errors::{
|
||||
InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern,
|
||||
ParenRangeSuggestion, PatternOnWrongSideOfAt, RemoveLet, RepeatedMutInPattern,
|
||||
SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg,
|
||||
TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedLifetimeInPattern,
|
||||
UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
|
||||
TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedExpressionInPatternSugg,
|
||||
UnexpectedLifetimeInPattern, UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
|
||||
UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens,
|
||||
};
|
||||
use crate::parser::expr::could_be_unclosed_char_literal;
|
||||
use crate::parser::expr::{could_be_unclosed_char_literal, DestructuredFloat};
|
||||
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
||||
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
@ -342,7 +344,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures that the last parsed pattern (or pattern range bound) is not followed by a method call or an operator.
|
||||
/// Ensures that the last parsed pattern (or pattern range bound) is not followed by an expression.
|
||||
///
|
||||
/// `is_end_bound` indicates whether the last parsed thing was the end bound of a range pattern (see [`parse_pat_range_end`](Self::parse_pat_range_end))
|
||||
/// in order to say "expected a pattern range bound" instead of "expected a pattern";
|
||||
@ -350,38 +352,64 @@ impl<'a> Parser<'a> {
|
||||
/// 0..=1 + 2
|
||||
/// ^^^^^
|
||||
/// ```
|
||||
/// Only the end bound is spanned, and this function have no idea if there were a `..=` before `pat_span`, hence the parameter.
|
||||
/// Only the end bound is spanned in this case, and this function has no idea if there was a `..=` before `pat_span`, hence the parameter.
|
||||
///
|
||||
/// This function returns `Some` if a trailing expression was recovered, and said expression's span.
|
||||
#[must_use = "the pattern must be discarded as `PatKind::Err` if this function returns Some"]
|
||||
fn maybe_recover_trailing_expr(
|
||||
&mut self,
|
||||
pat_span: Span,
|
||||
is_end_bound: bool,
|
||||
) -> Option<ErrorGuaranteed> {
|
||||
) -> Option<(ErrorGuaranteed, Span)> {
|
||||
if self.prev_token.is_keyword(kw::Underscore) || !self.may_recover() {
|
||||
// Don't recover anything after an `_` or if recovery is disabled.
|
||||
return None;
|
||||
}
|
||||
|
||||
// Check for `.hello()`, but allow `.Hello()` to be recovered as `, Hello()` in `parse_seq_to_before_tokens()`.
|
||||
let has_trailing_method = self.check_noexpect(&token::Dot)
|
||||
// Returns `true` iff `token` is an unsuffixed integer.
|
||||
let is_one_tuple_index = |_: &Self, token: &Token| -> bool {
|
||||
use token::{Lit, LitKind};
|
||||
|
||||
matches!(
|
||||
token.kind,
|
||||
token::Literal(Lit { kind: LitKind::Integer, symbol: _, suffix: None })
|
||||
)
|
||||
};
|
||||
|
||||
// Returns `true` iff `token` is an unsuffixed `x.y` float.
|
||||
let is_two_tuple_indexes = |this: &Self, token: &Token| -> bool {
|
||||
use token::{Lit, LitKind};
|
||||
|
||||
if let token::Literal(Lit { kind: LitKind::Float, symbol, suffix: None }) = token.kind
|
||||
&& let DestructuredFloat::MiddleDot(..) = this.break_up_float(symbol, token.span)
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
// Check for `.hello` or `.0`.
|
||||
let has_dot_expr = self.check_noexpect(&token::Dot) // `.`
|
||||
&& self.look_ahead(1, |tok| {
|
||||
tok.ident()
|
||||
.and_then(|(ident, _)| ident.name.as_str().chars().next())
|
||||
.is_some_and(char::is_lowercase)
|
||||
})
|
||||
&& self.look_ahead(2, |t| *t == token::OpenDelim(Delimiter::Parenthesis));
|
||||
tok.is_ident() // `hello`
|
||||
|| is_one_tuple_index(&self, &tok) // `0`
|
||||
|| is_two_tuple_indexes(&self, &tok) // `0.0`
|
||||
});
|
||||
|
||||
// Check for operators.
|
||||
// `|` is excluded as it is used in pattern alternatives and lambdas,
|
||||
// `?` is included for error propagation,
|
||||
// `[` is included for indexing operations,
|
||||
// `[]` is excluded as `a[]` isn't an expression and should be recovered as `a, []` (cf. `tests/ui/parser/pat-lt-bracket-7.rs`)
|
||||
// `[]` is excluded as `a[]` isn't an expression and should be recovered as `a, []` (cf. `tests/ui/parser/pat-lt-bracket-7.rs`),
|
||||
// `as` is included for type casts
|
||||
let has_trailing_operator = matches!(self.token.kind, token::BinOp(op) if op != BinOpToken::Or)
|
||||
|| self.token == token::Question
|
||||
|| (self.token == token::OpenDelim(Delimiter::Bracket)
|
||||
&& self.look_ahead(1, |t| *t != token::CloseDelim(Delimiter::Bracket)));
|
||||
&& self.look_ahead(1, |t| *t != token::CloseDelim(Delimiter::Bracket))) // excludes `[]`
|
||||
|| self.token.is_keyword(kw::As);
|
||||
|
||||
if !has_trailing_method && !has_trailing_operator {
|
||||
if !has_dot_expr && !has_trailing_operator {
|
||||
// Nothing to recover here.
|
||||
return None;
|
||||
}
|
||||
@ -391,44 +419,248 @@ impl<'a> Parser<'a> {
|
||||
snapshot.restrictions.insert(Restrictions::IS_PAT);
|
||||
|
||||
// Parse `?`, `.f`, `(arg0, arg1, ...)` or `[expr]` until they've all been eaten.
|
||||
if let Ok(expr) = snapshot
|
||||
let Ok(expr) = snapshot
|
||||
.parse_expr_dot_or_call_with(
|
||||
AttrVec::new(),
|
||||
self.mk_expr(pat_span, ExprKind::Dummy), // equivalent to transforming the parsed pattern into an `Expr`
|
||||
pat_span,
|
||||
)
|
||||
.map_err(|err| err.cancel())
|
||||
{
|
||||
let non_assoc_span = expr.span;
|
||||
else {
|
||||
// We got a trailing method/operator, but that wasn't an expression.
|
||||
return None;
|
||||
};
|
||||
|
||||
// Parse an associative expression such as `+ expr`, `% expr`, ...
|
||||
// Assignments, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
|
||||
if let Ok((expr, _)) =
|
||||
snapshot.parse_expr_assoc_rest_with(0, false, expr).map_err(|err| err.cancel())
|
||||
{
|
||||
// We got a valid expression.
|
||||
self.restore_snapshot(snapshot);
|
||||
self.restrictions.remove(Restrictions::IS_PAT);
|
||||
// Parse an associative expression such as `+ expr`, `% expr`, ...
|
||||
// Assignments, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
|
||||
let Ok((expr, _)) =
|
||||
snapshot.parse_expr_assoc_rest_with(0, false, expr).map_err(|err| err.cancel())
|
||||
else {
|
||||
// We got a trailing method/operator, but that wasn't an expression.
|
||||
return None;
|
||||
};
|
||||
|
||||
let is_bound = is_end_bound
|
||||
// is_start_bound: either `..` or `)..`
|
||||
|| self.token.is_range_separator()
|
||||
|| self.token == token::CloseDelim(Delimiter::Parenthesis)
|
||||
&& self.look_ahead(1, Token::is_range_separator);
|
||||
// We got a valid expression.
|
||||
self.restore_snapshot(snapshot);
|
||||
self.restrictions.remove(Restrictions::IS_PAT);
|
||||
|
||||
// Check that `parse_expr_assoc_with` didn't eat a rhs.
|
||||
let is_method_call = has_trailing_method && non_assoc_span == expr.span;
|
||||
let is_bound = is_end_bound
|
||||
// is_start_bound: either `..` or `)..`
|
||||
|| self.token.is_range_separator()
|
||||
|| self.token == token::CloseDelim(Delimiter::Parenthesis)
|
||||
&& self.look_ahead(1, Token::is_range_separator);
|
||||
|
||||
return Some(self.dcx().emit_err(UnexpectedExpressionInPattern {
|
||||
span: expr.span,
|
||||
let span = expr.span;
|
||||
|
||||
Some((
|
||||
self.dcx()
|
||||
.create_err(UnexpectedExpressionInPattern {
|
||||
span,
|
||||
is_bound,
|
||||
is_method_call,
|
||||
}));
|
||||
expr_precedence: expr.precedence().order(),
|
||||
})
|
||||
.stash(span, StashKey::ExprInPat)
|
||||
.unwrap(),
|
||||
span,
|
||||
))
|
||||
}
|
||||
|
||||
/// Called by [`Parser::parse_stmt_without_recovery`], used to add statement-aware subdiagnostics to the errors stashed
|
||||
/// by [`Parser::maybe_recover_trailing_expr`].
|
||||
pub(super) fn maybe_augment_stashed_expr_in_pats_with_suggestions(&mut self, stmt: &Stmt) {
|
||||
if self.dcx().has_errors().is_none() {
|
||||
// No need to walk the statement if there's no stashed errors.
|
||||
return;
|
||||
}
|
||||
|
||||
struct PatVisitor<'a> {
|
||||
/// `self`
|
||||
parser: &'a Parser<'a>,
|
||||
/// The freshly-parsed statement.
|
||||
stmt: &'a Stmt,
|
||||
/// The current match arm (for arm guard suggestions).
|
||||
arm: Option<&'a Arm>,
|
||||
/// The current struct field (for variable name suggestions).
|
||||
field: Option<&'a PatField>,
|
||||
}
|
||||
|
||||
impl<'a> PatVisitor<'a> {
|
||||
/// Looks for stashed [`StashKey::ExprInPat`] errors in `stash_span`, and emit them with suggestions.
|
||||
/// `stash_span` is contained in `expr_span`, the latter being larger in borrow patterns;
|
||||
/// ```txt
|
||||
/// &mut x.y
|
||||
/// -----^^^ `stash_span`
|
||||
/// |
|
||||
/// `expr_span`
|
||||
/// ```
|
||||
/// `is_range_bound` is used to exclude arm guard suggestions in range pattern bounds.
|
||||
fn maybe_add_suggestions_then_emit(
|
||||
&self,
|
||||
stash_span: Span,
|
||||
expr_span: Span,
|
||||
is_range_bound: bool,
|
||||
) {
|
||||
self.parser.dcx().try_steal_modify_and_emit_err(
|
||||
stash_span,
|
||||
StashKey::ExprInPat,
|
||||
|err| {
|
||||
// Includes pre-pats (e.g. `&mut <err>`) in the diagnostic.
|
||||
err.span.replace(stash_span, expr_span);
|
||||
|
||||
let sm = self.parser.psess.source_map();
|
||||
let stmt = self.stmt;
|
||||
let line_lo = sm.span_extend_to_line(stmt.span).shrink_to_lo();
|
||||
let indentation = sm.indentation_before(stmt.span).unwrap_or_default();
|
||||
let Ok(expr) = self.parser.span_to_snippet(expr_span) else {
|
||||
// FIXME: some suggestions don't actually need the snippet; see PR #123877's unresolved conversations.
|
||||
return;
|
||||
};
|
||||
|
||||
if let StmtKind::Let(local) = &stmt.kind {
|
||||
match &local.kind {
|
||||
LocalKind::Decl | LocalKind::Init(_) => {
|
||||
// It's kinda hard to guess what the user intended, so don't make suggestions.
|
||||
return;
|
||||
}
|
||||
|
||||
LocalKind::InitElse(_, _) => {}
|
||||
}
|
||||
}
|
||||
|
||||
// help: use an arm guard `if val == expr`
|
||||
// FIXME(guard_patterns): suggest this regardless of a match arm.
|
||||
if let Some(arm) = &self.arm
|
||||
&& !is_range_bound
|
||||
{
|
||||
let (ident, ident_span) = match self.field {
|
||||
Some(field) => {
|
||||
(field.ident.to_string(), field.ident.span.to(expr_span))
|
||||
}
|
||||
None => ("val".to_owned(), expr_span),
|
||||
};
|
||||
|
||||
// Are parentheses required around `expr`?
|
||||
// HACK: a neater way would be preferable.
|
||||
let expr = match &err.args["expr_precedence"] {
|
||||
DiagArgValue::Number(expr_precedence) => {
|
||||
if *expr_precedence
|
||||
<= ExprPrecedence::Binary(BinOpKind::Eq).order() as i32
|
||||
{
|
||||
format!("({expr})")
|
||||
} else {
|
||||
format!("{expr}")
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
match &arm.guard {
|
||||
None => {
|
||||
err.subdiagnostic(
|
||||
UnexpectedExpressionInPatternSugg::CreateGuard {
|
||||
ident_span,
|
||||
pat_hi: arm.pat.span.shrink_to_hi(),
|
||||
ident,
|
||||
expr,
|
||||
},
|
||||
);
|
||||
}
|
||||
Some(guard) => {
|
||||
// Are parentheses required around the old guard?
|
||||
let wrap_guard = guard.precedence().order()
|
||||
<= ExprPrecedence::Binary(BinOpKind::And).order();
|
||||
|
||||
err.subdiagnostic(
|
||||
UnexpectedExpressionInPatternSugg::UpdateGuard {
|
||||
ident_span,
|
||||
guard_lo: if wrap_guard {
|
||||
Some(guard.span.shrink_to_lo())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
guard_hi: guard.span.shrink_to_hi(),
|
||||
guard_hi_paren: if wrap_guard { ")" } else { "" },
|
||||
ident,
|
||||
expr,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// help: extract the expr into a `const VAL: _ = expr`
|
||||
let ident = match self.field {
|
||||
Some(field) => field.ident.as_str().to_uppercase(),
|
||||
None => "VAL".to_owned(),
|
||||
};
|
||||
err.subdiagnostic(UnexpectedExpressionInPatternSugg::Const {
|
||||
stmt_lo: line_lo,
|
||||
ident_span: expr_span,
|
||||
expr,
|
||||
ident,
|
||||
indentation,
|
||||
});
|
||||
|
||||
// help: wrap the expr in a `const { expr }`
|
||||
// FIXME(inline_const_pat): once stabilized, remove this check and remove the `(requires #[feature(inline_const_pat)])` note from the message
|
||||
if self.parser.psess.unstable_features.is_nightly_build() {
|
||||
err.subdiagnostic(UnexpectedExpressionInPatternSugg::InlineConst {
|
||||
start_span: expr_span.shrink_to_lo(),
|
||||
end_span: expr_span.shrink_to_hi(),
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// We got a trailing method/operator, but we couldn't parse an expression.
|
||||
None
|
||||
impl<'a> Visitor<'a> for PatVisitor<'a> {
|
||||
fn visit_arm(&mut self, a: &'a Arm) -> Self::Result {
|
||||
self.arm = Some(a);
|
||||
visit::walk_arm(self, a);
|
||||
self.arm = None;
|
||||
}
|
||||
|
||||
fn visit_pat_field(&mut self, fp: &'a PatField) -> Self::Result {
|
||||
self.field = Some(fp);
|
||||
visit::walk_pat_field(self, fp);
|
||||
self.field = None;
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, p: &'a Pat) -> Self::Result {
|
||||
match &p.kind {
|
||||
// Base expression
|
||||
PatKind::Err(_) | PatKind::Lit(_) => {
|
||||
self.maybe_add_suggestions_then_emit(p.span, p.span, false)
|
||||
}
|
||||
|
||||
// Sub-patterns
|
||||
// FIXME: this doesn't work with recursive subpats (`&mut &mut <err>`)
|
||||
PatKind::Box(subpat) | PatKind::Ref(subpat, _)
|
||||
if matches!(subpat.kind, PatKind::Err(_) | PatKind::Lit(_)) =>
|
||||
{
|
||||
self.maybe_add_suggestions_then_emit(subpat.span, p.span, false)
|
||||
}
|
||||
|
||||
// Sub-expressions
|
||||
PatKind::Range(start, end, _) => {
|
||||
if let Some(start) = start {
|
||||
self.maybe_add_suggestions_then_emit(start.span, start.span, true);
|
||||
}
|
||||
|
||||
if let Some(end) = end {
|
||||
self.maybe_add_suggestions_then_emit(end.span, end.span, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Walk continuation
|
||||
_ => visit::walk_pat(self, p),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Starts the visit.
|
||||
PatVisitor { parser: self, stmt, arm: None, field: None }.visit_stmt(stmt);
|
||||
}
|
||||
|
||||
/// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
|
||||
@ -544,7 +776,7 @@ impl<'a> Parser<'a> {
|
||||
self.parse_pat_tuple_struct(qself, path)?
|
||||
} else {
|
||||
match self.maybe_recover_trailing_expr(span, false) {
|
||||
Some(guar) => PatKind::Err(guar),
|
||||
Some((guar, _)) => PatKind::Err(guar),
|
||||
None => PatKind::Path(qself, path),
|
||||
}
|
||||
}
|
||||
@ -577,10 +809,10 @@ impl<'a> Parser<'a> {
|
||||
// Try to parse everything else as literal with optional minus
|
||||
match self.parse_literal_maybe_minus() {
|
||||
Ok(begin) => {
|
||||
let begin = match self.maybe_recover_trailing_expr(begin.span, false) {
|
||||
Some(guar) => self.mk_expr_err(begin.span, guar),
|
||||
None => begin,
|
||||
};
|
||||
let begin = self
|
||||
.maybe_recover_trailing_expr(begin.span, false)
|
||||
.map(|(guar, sp)| self.mk_expr_err(sp, guar))
|
||||
.unwrap_or(begin);
|
||||
|
||||
match self.parse_range_end() {
|
||||
Some(form) => self.parse_pat_range_begin_with(begin, form)?,
|
||||
@ -721,7 +953,8 @@ impl<'a> Parser<'a> {
|
||||
// For backward compatibility, `(..)` is a tuple pattern as well.
|
||||
let paren_pattern =
|
||||
fields.len() == 1 && !(matches!(trailing_comma, Trailing::Yes) || fields[0].is_rest());
|
||||
if paren_pattern {
|
||||
|
||||
let pat = if paren_pattern {
|
||||
let pat = fields.into_iter().next().unwrap();
|
||||
let close_paren = self.prev_token.span;
|
||||
|
||||
@ -739,7 +972,7 @@ impl<'a> Parser<'a> {
|
||||
},
|
||||
});
|
||||
|
||||
self.parse_pat_range_begin_with(begin.clone(), form)
|
||||
self.parse_pat_range_begin_with(begin.clone(), form)?
|
||||
}
|
||||
// recover ranges with parentheses around the `(start)..`
|
||||
PatKind::Err(guar)
|
||||
@ -754,15 +987,20 @@ impl<'a> Parser<'a> {
|
||||
},
|
||||
});
|
||||
|
||||
self.parse_pat_range_begin_with(self.mk_expr_err(pat.span, *guar), form)
|
||||
self.parse_pat_range_begin_with(self.mk_expr_err(pat.span, *guar), form)?
|
||||
}
|
||||
|
||||
// (pat) with optional parentheses
|
||||
_ => Ok(PatKind::Paren(pat)),
|
||||
_ => PatKind::Paren(pat),
|
||||
}
|
||||
} else {
|
||||
Ok(PatKind::Tuple(fields))
|
||||
}
|
||||
PatKind::Tuple(fields)
|
||||
};
|
||||
|
||||
Ok(match self.maybe_recover_trailing_expr(open_paren.to(self.prev_token.span), false) {
|
||||
None => pat,
|
||||
Some((guar, _)) => PatKind::Err(guar),
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse a mutable binding with the `mut` token already eaten.
|
||||
@ -816,7 +1054,7 @@ impl<'a> Parser<'a> {
|
||||
self.0 = true;
|
||||
*m = Mutability::Mut;
|
||||
}
|
||||
walk_pat(self, pat);
|
||||
mut_visit::walk_pat(self, pat);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1015,7 +1253,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
Ok(match recovered {
|
||||
Some(guar) => self.mk_expr_err(bound.span, guar),
|
||||
Some((guar, sp)) => self.mk_expr_err(sp, guar),
|
||||
None => bound,
|
||||
})
|
||||
}
|
||||
@ -1084,7 +1322,7 @@ impl<'a> Parser<'a> {
|
||||
// but not `ident @ subpat` as `subpat` was already checked and `ident` continues with `@`.
|
||||
|
||||
let pat = if sub.is_none()
|
||||
&& let Some(guar) = self.maybe_recover_trailing_expr(ident.span, false)
|
||||
&& let Some((guar, _)) = self.maybe_recover_trailing_expr(ident.span, false)
|
||||
{
|
||||
PatKind::Err(guar)
|
||||
} else {
|
||||
|
@ -29,6 +29,9 @@ use crate::{errors, maybe_whole};
|
||||
impl<'a> Parser<'a> {
|
||||
/// Parses a statement. This stops just before trailing semicolons on everything but items.
|
||||
/// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
|
||||
///
|
||||
/// If `force_collect` is [`ForceCollect::Yes`], forces collection of tokens regardless of
|
||||
/// whether or not we have attributes.
|
||||
// Public for rustfmt usage.
|
||||
pub(super) fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<Stmt>> {
|
||||
Ok(self.parse_stmt_without_recovery(false, force_collect).unwrap_or_else(|e| {
|
||||
@ -66,7 +69,7 @@ impl<'a> Parser<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
Ok(Some(if self.token.is_keyword(kw::Let) {
|
||||
let stmt = if self.token.is_keyword(kw::Let) {
|
||||
self.collect_tokens(None, attrs, force_collect, |this, attrs| {
|
||||
this.expect_keyword(kw::Let)?;
|
||||
let local = this.parse_local(attrs)?;
|
||||
@ -163,7 +166,10 @@ impl<'a> Parser<'a> {
|
||||
} else {
|
||||
self.error_outer_attrs(attrs);
|
||||
return Ok(None);
|
||||
}))
|
||||
};
|
||||
|
||||
self.maybe_augment_stashed_expr_in_pats_with_suggestions(&stmt);
|
||||
Ok(Some(stmt))
|
||||
}
|
||||
|
||||
fn parse_stmt_path_start(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> {
|
||||
|
@ -3,6 +3,17 @@ error: expected a pattern range bound, found an expression
|
||||
|
|
||||
LL | 0..5+1 => errors_only.push(x),
|
||||
| ^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 5+1;
|
||||
LL ~ match x as i32 {
|
||||
LL ~ 0..VAL => errors_only.push(x),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | 0..const { 5+1 } => errors_only.push(x),
|
||||
| +++++++ +
|
||||
|
||||
error[E0408]: variable `n` is not bound in all patterns
|
||||
--> $DIR/range_pat_interactions1.rs:10:25
|
||||
|
@ -1,9 +1,3 @@
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/range_pat_interactions2.rs:10:18
|
||||
|
|
||||
LL | 0..=(5+1) => errors_only.push(x),
|
||||
| ^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/range_pat_interactions2.rs:10:17
|
||||
|
|
||||
@ -16,6 +10,23 @@ LL - 0..=(5+1) => errors_only.push(x),
|
||||
LL + 0..=5+1 => errors_only.push(x),
|
||||
|
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/range_pat_interactions2.rs:10:18
|
||||
|
|
||||
LL | 0..=(5+1) => errors_only.push(x),
|
||||
| ^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 5+1;
|
||||
LL ~ match x as i32 {
|
||||
LL ~ 0..=(VAL) => errors_only.push(x),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | 0..=(const { 5+1 }) => errors_only.push(x),
|
||||
| +++++++ +
|
||||
|
||||
error[E0658]: inline-const in pattern position is experimental
|
||||
--> $DIR/range_pat_interactions2.rs:15:20
|
||||
|
|
||||
|
@ -1,5 +1,6 @@
|
||||
//@ error-pattern: expected
|
||||
|
||||
fn main() {
|
||||
let x.y::<isize>.z foo;
|
||||
//~^ error: field expressions cannot have generic arguments
|
||||
//~| error: expected a pattern, found an expression
|
||||
//~| error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator, found `foo`
|
||||
}
|
||||
|
@ -1,8 +1,20 @@
|
||||
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
--> $DIR/bad-name.rs:4:8
|
||||
error: field expressions cannot have generic arguments
|
||||
--> $DIR/bad-name.rs:2:12
|
||||
|
|
||||
LL | let x.y::<isize>.z foo;
|
||||
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/bad-name.rs:2:7
|
||||
|
|
||||
LL | let x.y::<isize>.z foo;
|
||||
| ^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator, found `foo`
|
||||
--> $DIR/bad-name.rs:2:22
|
||||
|
|
||||
LL | let x.y::<isize>.z foo;
|
||||
| ^^^ expected one of 9 possible tokens
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -3,6 +3,21 @@ error: expected a pattern, found an expression
|
||||
|
|
||||
LL | tmp[0] => {}
|
||||
| ^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == tmp[0] => {}
|
||||
| ~~~ ++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = tmp[0];
|
||||
LL ~ match z {
|
||||
LL ~ VAL => {}
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { tmp[0] } => {}
|
||||
| +++++++ +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/pat-lt-bracket-6.rs:5:15
|
||||
--> $DIR/pat-lt-bracket-6.rs:5:14
|
||||
|
|
||||
LL | let Test(&desc[..]) = x;
|
||||
| ^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
| ^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pat-lt-bracket-6.rs:10:30
|
||||
|
@ -1,28 +0,0 @@
|
||||
fn main() {
|
||||
match u8::MAX {
|
||||
u8::MAX.abs() => (),
|
||||
//~^ error: expected a pattern, found a method call
|
||||
x.sqrt() @ .. => (),
|
||||
//~^ error: expected a pattern, found a method call
|
||||
//~| error: left-hand side of `@` must be a binding
|
||||
z @ w @ v.u() => (),
|
||||
//~^ error: expected a pattern, found a method call
|
||||
y.ilog(3) => (),
|
||||
//~^ error: expected a pattern, found a method call
|
||||
n + 1 => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
("".f() + 14 * 8) => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
0 | ((1) | 2) | 3 => (),
|
||||
f?() => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
(_ + 1) => (),
|
||||
//~^ error: expected one of `)`, `,`, or `|`, found `+`
|
||||
}
|
||||
|
||||
let 1 + 1 = 2;
|
||||
//~^ error: expected a pattern, found an expression
|
||||
|
||||
let b = matches!(x, (x * x | x.f()) | x[0]);
|
||||
//~^ error: expected one of `)`, `,`, `@`, or `|`, found `*`
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
error: expected a pattern, found a method call
|
||||
--> $DIR/pat-recover-exprs.rs:3:9
|
||||
|
|
||||
LL | u8::MAX.abs() => (),
|
||||
| ^^^^^^^^^^^^^ method calls are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found a method call
|
||||
--> $DIR/pat-recover-exprs.rs:5:9
|
||||
|
|
||||
LL | x.sqrt() @ .. => (),
|
||||
| ^^^^^^^^ method calls are not allowed in patterns
|
||||
|
||||
error: left-hand side of `@` must be a binding
|
||||
--> $DIR/pat-recover-exprs.rs:5:9
|
||||
|
|
||||
LL | x.sqrt() @ .. => (),
|
||||
| --------^^^--
|
||||
| | |
|
||||
| | also a pattern
|
||||
| interpreted as a pattern, not a binding
|
||||
|
|
||||
= note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`
|
||||
|
||||
error: expected a pattern, found a method call
|
||||
--> $DIR/pat-recover-exprs.rs:8:17
|
||||
|
|
||||
LL | z @ w @ v.u() => (),
|
||||
| ^^^^^ method calls are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found a method call
|
||||
--> $DIR/pat-recover-exprs.rs:10:9
|
||||
|
|
||||
LL | y.ilog(3) => (),
|
||||
| ^^^^^^^^^ method calls are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/pat-recover-exprs.rs:12:9
|
||||
|
|
||||
LL | n + 1 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/pat-recover-exprs.rs:14:10
|
||||
|
|
||||
LL | ("".f() + 14 * 8) => (),
|
||||
| ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/pat-recover-exprs.rs:17:9
|
||||
|
|
||||
LL | f?() => (),
|
||||
| ^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected one of `)`, `,`, or `|`, found `+`
|
||||
--> $DIR/pat-recover-exprs.rs:19:12
|
||||
|
|
||||
LL | (_ + 1) => (),
|
||||
| ^ expected one of `)`, `,`, or `|`
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/pat-recover-exprs.rs:23:9
|
||||
|
|
||||
LL | let 1 + 1 = 2;
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected one of `)`, `,`, `@`, or `|`, found `*`
|
||||
--> $DIR/pat-recover-exprs.rs:26:28
|
||||
|
|
||||
LL | let b = matches!(x, (x * x | x.f()) | x[0]);
|
||||
| ^ expected one of `)`, `,`, `@`, or `|`
|
||||
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
|
|
||||
= note: while parsing argument for this `pat` macro fragment
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
@ -1,37 +0,0 @@
|
||||
struct Foo(String);
|
||||
struct Bar { baz: String }
|
||||
|
||||
fn foo(foo: Foo) -> bool {
|
||||
match foo {
|
||||
Foo("hi".to_owned()) => true,
|
||||
//~^ error: expected a pattern, found a method call
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn bar(bar: Bar) -> bool {
|
||||
match bar {
|
||||
Bar { baz: "hi".to_owned() } => true,
|
||||
//~^ error: expected a pattern, found a method call
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn baz() { // issue #90121
|
||||
let foo = vec!["foo".to_string()];
|
||||
|
||||
match foo.as_slice() {
|
||||
&["foo".to_string()] => {}
|
||||
//~^ error: expected a pattern, found a method call
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if let (-1.some(4)) = (0, Some(4)) {}
|
||||
//~^ error: expected a pattern, found a method call
|
||||
|
||||
if let (-1.Some(4)) = (0, Some(4)) {}
|
||||
//~^ error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
|
||||
//~| help: missing `,`
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
error: expected a pattern, found a method call
|
||||
--> $DIR/pat-recover-methodcalls.rs:6:13
|
||||
|
|
||||
LL | Foo("hi".to_owned()) => true,
|
||||
| ^^^^^^^^^^^^^^^ method calls are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found a method call
|
||||
--> $DIR/pat-recover-methodcalls.rs:14:20
|
||||
|
|
||||
LL | Bar { baz: "hi".to_owned() } => true,
|
||||
| ^^^^^^^^^^^^^^^ method calls are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found a method call
|
||||
--> $DIR/pat-recover-methodcalls.rs:24:11
|
||||
|
|
||||
LL | &["foo".to_string()] => {}
|
||||
| ^^^^^^^^^^^^^^^^^ method calls are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found a method call
|
||||
--> $DIR/pat-recover-methodcalls.rs:31:13
|
||||
|
|
||||
LL | if let (-1.some(4)) = (0, Some(4)) {}
|
||||
| ^^^^^^^^^^ method calls are not allowed in patterns
|
||||
|
||||
error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
|
||||
--> $DIR/pat-recover-methodcalls.rs:34:15
|
||||
|
|
||||
LL | if let (-1.Some(4)) = (0, Some(4)) {}
|
||||
| ^
|
||||
| |
|
||||
| expected one of `)`, `,`, `...`, `..=`, `..`, or `|`
|
||||
| help: missing `,`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
@ -1,132 +0,0 @@
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/pat-recover-ranges.rs:4:13
|
||||
|
|
||||
LL | 0..=(1) => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - 0..=(1) => (),
|
||||
LL + 0..=1 => (),
|
||||
|
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/pat-recover-ranges.rs:6:9
|
||||
|
|
||||
LL | (-12)..=4 => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (-12)..=4 => (),
|
||||
LL + -12..=4 => (),
|
||||
|
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/pat-recover-ranges.rs:8:9
|
||||
|
|
||||
LL | (0)..=(-4) => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (0)..=(-4) => (),
|
||||
LL + 0..=(-4) => (),
|
||||
|
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/pat-recover-ranges.rs:8:15
|
||||
|
|
||||
LL | (0)..=(-4) => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (0)..=(-4) => (),
|
||||
LL + (0)..=-4 => (),
|
||||
|
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/pat-recover-ranges.rs:11:12
|
||||
|
|
||||
LL | ..=1 + 2 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/pat-recover-ranges.rs:13:9
|
||||
|
|
||||
LL | (4).. => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (4).. => (),
|
||||
LL + 4.. => (),
|
||||
|
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/pat-recover-ranges.rs:15:10
|
||||
|
|
||||
LL | (-4 + 0).. => (),
|
||||
| ^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/pat-recover-ranges.rs:15:9
|
||||
|
|
||||
LL | (-4 + 0).. => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (-4 + 0).. => (),
|
||||
LL + -4 + 0.. => (),
|
||||
|
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/pat-recover-ranges.rs:18:10
|
||||
|
|
||||
LL | (1 + 4)...1 * 2 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/pat-recover-ranges.rs:18:9
|
||||
|
|
||||
LL | (1 + 4)...1 * 2 => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (1 + 4)...1 * 2 => (),
|
||||
LL + 1 + 4...1 * 2 => (),
|
||||
|
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/pat-recover-ranges.rs:18:19
|
||||
|
|
||||
LL | (1 + 4)...1 * 2 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern range bound, found a method call
|
||||
--> $DIR/pat-recover-ranges.rs:24:9
|
||||
|
|
||||
LL | 0.x()..="y".z() => (),
|
||||
| ^^^^^ method calls are not allowed in patterns
|
||||
|
||||
error: expected a pattern range bound, found a method call
|
||||
--> $DIR/pat-recover-ranges.rs:24:17
|
||||
|
|
||||
LL | 0.x()..="y".z() => (),
|
||||
| ^^^^^^^ method calls are not allowed in patterns
|
||||
|
||||
warning: `...` range patterns are deprecated
|
||||
--> $DIR/pat-recover-ranges.rs:18:16
|
||||
|
|
||||
LL | (1 + 4)...1 * 2 => (),
|
||||
| ^^^ help: use `..=` for an inclusive range
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(ellipsis_inclusive_range_patterns)]` on by default
|
||||
|
||||
error: aborting due to 13 previous errors; 1 warning emitted
|
||||
|
106
tests/ui/parser/recover/recover-pat-exprs.rs
Normal file
106
tests/ui/parser/recover/recover-pat-exprs.rs
Normal file
@ -0,0 +1,106 @@
|
||||
// FieldExpression, TupleIndexingExpression
|
||||
fn field_access() {
|
||||
match 0 {
|
||||
x => (),
|
||||
x.y => (), //~ error: expected a pattern, found an expression
|
||||
x.0 => (), //~ error: expected a pattern, found an expression
|
||||
x._0 => (), //~ error: expected a pattern, found an expression
|
||||
x.0.1 => (), //~ error: expected a pattern, found an expression
|
||||
x.4.y.17.__z => (), //~ error: expected a pattern, found an expression
|
||||
}
|
||||
|
||||
{ let x.0e0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
{ let x.-0.0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
{ let x.-0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
|
||||
{ let x.0u32; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
{ let x.0.0_f64; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
}
|
||||
|
||||
// IndexExpression, ArrayExpression
|
||||
fn array_indexing() {
|
||||
match 0 {
|
||||
x[0] => (), //~ error: expected a pattern, found an expression
|
||||
x[..] => (), //~ error: expected a pattern, found an expression
|
||||
}
|
||||
|
||||
{ let x[0, 1, 2]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
|
||||
{ let x[0; 20]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
|
||||
{ let x[]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
|
||||
{ let (x[]); } //~ error: expected one of `)`, `,`, `@`, or `|`, found `[`
|
||||
//~^ missing `,`
|
||||
}
|
||||
|
||||
// MethodCallExpression, CallExpression, ErrorPropagationExpression
|
||||
fn method_call() {
|
||||
match 0 {
|
||||
x.f() => (), //~ error: expected a pattern, found an expression
|
||||
x._f() => (), //~ error: expected a pattern, found an expression
|
||||
x? => (), //~ error: expected a pattern, found an expression
|
||||
().f() => (), //~ error: expected a pattern, found an expression
|
||||
(0, x)?.f() => (), //~ error: expected a pattern, found an expression
|
||||
x.f().g() => (), //~ error: expected a pattern, found an expression
|
||||
0.f()?.g()?? => (), //~ error: expected a pattern, found an expression
|
||||
}
|
||||
}
|
||||
|
||||
// TypeCastExpression
|
||||
fn type_cast() {
|
||||
match 0 {
|
||||
x as usize => (), //~ error: expected a pattern, found an expression
|
||||
0 as usize => (), //~ error: expected a pattern, found an expression
|
||||
x.f().0.4 as f32 => (), //~ error: expected a pattern, found an expression
|
||||
}
|
||||
}
|
||||
|
||||
// ArithmeticOrLogicalExpression, also check if parentheses are added as needed
|
||||
fn operator() {
|
||||
match 0 {
|
||||
1 + 1 => (), //~ error: expected a pattern, found an expression
|
||||
(1 + 2) * 3 => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
//~| error: expected a pattern, found an expression
|
||||
x.0 > 2 => (), //~ error: expected a pattern, found an expression
|
||||
x.0 == 2 => (), //~ error: expected a pattern, found an expression
|
||||
}
|
||||
|
||||
// preexisting match arm guard
|
||||
match (0, 0) {
|
||||
(x, y.0 > 2) if x != 0 => (), //~ error: expected a pattern, found an expression
|
||||
(x, y.0 > 2) if x != 0 || x != 1 => (), //~ error: expected a pattern, found an expression
|
||||
}
|
||||
}
|
||||
|
||||
const _: u32 = match 12 {
|
||||
1 + 2 * PI.cos() => 2, //~ error: expected a pattern, found an expression
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
match u8::MAX {
|
||||
u8::MAX.abs() => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
x.sqrt() @ .. => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
//~| error: left-hand side of `@` must be a binding
|
||||
z @ w @ v.u() => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
y.ilog(3) => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
n + 1 => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
("".f() + 14 * 8) => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
0 | ((1) | 2) | 3 => (),
|
||||
f?() => (),
|
||||
//~^ error: expected a pattern, found an expression
|
||||
(_ + 1) => (),
|
||||
//~^ error: expected one of `)`, `,`, or `|`, found `+`
|
||||
}
|
||||
|
||||
let 1 + 1 = 2;
|
||||
//~^ error: expected a pattern, found an expression
|
||||
|
||||
let b = matches!(x, (x * x | x.f()) | x[0]);
|
||||
//~^ error: expected one of `)`, `,`, `@`, or `|`, found `*`
|
||||
}
|
772
tests/ui/parser/recover/recover-pat-exprs.stderr
Normal file
772
tests/ui/parser/recover/recover-pat-exprs.stderr
Normal file
@ -0,0 +1,772 @@
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:5:9
|
||||
|
|
||||
LL | x.y => (),
|
||||
| ^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x.y => (),
|
||||
| ~~~ +++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x.y;
|
||||
LL ~ match 0 {
|
||||
LL | x => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x.y } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:6:9
|
||||
|
|
||||
LL | x.0 => (),
|
||||
| ^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x.0 => (),
|
||||
| ~~~ +++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x.0;
|
||||
LL ~ match 0 {
|
||||
LL | x => (),
|
||||
LL | x.y => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x.0 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:7:9
|
||||
|
|
||||
LL | x._0 => (),
|
||||
| ^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x._0 => (),
|
||||
| ~~~ ++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x._0;
|
||||
LL ~ match 0 {
|
||||
LL | x => (),
|
||||
LL | x.y => (),
|
||||
LL | x.0 => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x._0 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:8:9
|
||||
|
|
||||
LL | x.0.1 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x.0.1 => (),
|
||||
| ~~~ +++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x.0.1;
|
||||
LL ~ match 0 {
|
||||
LL | x => (),
|
||||
...
|
||||
LL | x._0 => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x.0.1 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:9:9
|
||||
|
|
||||
LL | x.4.y.17.__z => (),
|
||||
| ^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x.4.y.17.__z => (),
|
||||
| ~~~ ++++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x.4.y.17.__z;
|
||||
LL ~ match 0 {
|
||||
LL | x => (),
|
||||
...
|
||||
LL | x.0.1 => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x.4.y.17.__z } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
--> $DIR/recover-pat-exprs.rs:12:12
|
||||
|
|
||||
LL | { let x.0e0; }
|
||||
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
|
||||
|
||||
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
--> $DIR/recover-pat-exprs.rs:13:12
|
||||
|
|
||||
LL | { let x.-0.0; }
|
||||
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
|
||||
|
||||
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
--> $DIR/recover-pat-exprs.rs:14:12
|
||||
|
|
||||
LL | { let x.-0; }
|
||||
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
|
||||
|
||||
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
--> $DIR/recover-pat-exprs.rs:16:12
|
||||
|
|
||||
LL | { let x.0u32; }
|
||||
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
|
||||
|
||||
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
|
||||
--> $DIR/recover-pat-exprs.rs:17:12
|
||||
|
|
||||
LL | { let x.0.0_f64; }
|
||||
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:23:9
|
||||
|
|
||||
LL | x[0] => (),
|
||||
| ^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x[0] => (),
|
||||
| ~~~ ++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x[0];
|
||||
LL ~ match 0 {
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x[0] } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:24:9
|
||||
|
|
||||
LL | x[..] => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x[..] => (),
|
||||
| ~~~ +++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x[..];
|
||||
LL ~ match 0 {
|
||||
LL | x[0] => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x[..] } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
|
||||
--> $DIR/recover-pat-exprs.rs:27:12
|
||||
|
|
||||
LL | { let x[0, 1, 2]; }
|
||||
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
|
||||
|
||||
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
|
||||
--> $DIR/recover-pat-exprs.rs:28:12
|
||||
|
|
||||
LL | { let x[0; 20]; }
|
||||
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
|
||||
|
||||
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
|
||||
--> $DIR/recover-pat-exprs.rs:29:12
|
||||
|
|
||||
LL | { let x[]; }
|
||||
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
|
||||
|
||||
error: expected one of `)`, `,`, `@`, or `|`, found `[`
|
||||
--> $DIR/recover-pat-exprs.rs:30:13
|
||||
|
|
||||
LL | { let (x[]); }
|
||||
| ^
|
||||
| |
|
||||
| expected one of `)`, `,`, `@`, or `|`
|
||||
| help: missing `,`
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:37:9
|
||||
|
|
||||
LL | x.f() => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x.f() => (),
|
||||
| ~~~ +++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x.f();
|
||||
LL ~ match 0 {
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x.f() } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:38:9
|
||||
|
|
||||
LL | x._f() => (),
|
||||
| ^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x._f() => (),
|
||||
| ~~~ ++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x._f();
|
||||
LL ~ match 0 {
|
||||
LL | x.f() => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x._f() } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:39:9
|
||||
|
|
||||
LL | x? => (),
|
||||
| ^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x? => (),
|
||||
| ~~~ ++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x?;
|
||||
LL ~ match 0 {
|
||||
LL | x.f() => (),
|
||||
LL | x._f() => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x? } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:40:9
|
||||
|
|
||||
LL | ().f() => (),
|
||||
| ^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == ().f() => (),
|
||||
| ~~~ ++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = ().f();
|
||||
LL ~ match 0 {
|
||||
LL | x.f() => (),
|
||||
LL | x._f() => (),
|
||||
LL | x? => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { ().f() } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:41:9
|
||||
|
|
||||
LL | (0, x)?.f() => (),
|
||||
| ^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == (0, x)?.f() => (),
|
||||
| ~~~ +++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = (0, x)?.f();
|
||||
LL ~ match 0 {
|
||||
LL | x.f() => (),
|
||||
...
|
||||
LL | ().f() => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { (0, x)?.f() } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:42:9
|
||||
|
|
||||
LL | x.f().g() => (),
|
||||
| ^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x.f().g() => (),
|
||||
| ~~~ +++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x.f().g();
|
||||
LL ~ match 0 {
|
||||
LL | x.f() => (),
|
||||
...
|
||||
LL | (0, x)?.f() => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x.f().g() } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:43:9
|
||||
|
|
||||
LL | 0.f()?.g()?? => (),
|
||||
| ^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == 0.f()?.g()?? => (),
|
||||
| ~~~ ++++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 0.f()?.g()??;
|
||||
LL ~ match 0 {
|
||||
LL | x.f() => (),
|
||||
...
|
||||
LL | x.f().g() => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { 0.f()?.g()?? } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:50:9
|
||||
|
|
||||
LL | x as usize => (),
|
||||
| ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x as usize => (),
|
||||
| ~~~ ++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x as usize;
|
||||
LL ~ match 0 {
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x as usize } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:51:9
|
||||
|
|
||||
LL | 0 as usize => (),
|
||||
| ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == 0 as usize => (),
|
||||
| ~~~ ++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 0 as usize;
|
||||
LL ~ match 0 {
|
||||
LL | x as usize => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { 0 as usize } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:52:9
|
||||
|
|
||||
LL | x.f().0.4 as f32 => (),
|
||||
| ^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == x.f().0.4 as f32 => (),
|
||||
| ~~~ ++++++++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x.f().0.4 as f32;
|
||||
LL ~ match 0 {
|
||||
LL | x as usize => (),
|
||||
LL | 0 as usize => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x.f().0.4 as f32 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:59:9
|
||||
|
|
||||
LL | 1 + 1 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == 1 + 1 => (),
|
||||
| ~~~ +++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 1 + 1;
|
||||
LL ~ match 0 {
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { 1 + 1 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:60:9
|
||||
|
|
||||
LL | (1 + 2) * 3 => (),
|
||||
| ^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == (1 + 2) * 3 => (),
|
||||
| ~~~ +++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = (1 + 2) * 3;
|
||||
LL ~ match 0 {
|
||||
LL | 1 + 1 => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { (1 + 2) * 3 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:63:9
|
||||
|
|
||||
LL | x.0 > 2 => (),
|
||||
| ^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == (x.0 > 2) => (),
|
||||
| ~~~ +++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x.0 > 2;
|
||||
LL ~ match 0 {
|
||||
LL | 1 + 1 => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x.0 > 2 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:64:9
|
||||
|
|
||||
LL | x.0 == 2 => (),
|
||||
| ^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == (x.0 == 2) => (),
|
||||
| ~~~ ++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = x.0 == 2;
|
||||
LL ~ match 0 {
|
||||
LL | 1 + 1 => (),
|
||||
...
|
||||
LL | x.0 > 2 => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { x.0 == 2 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:69:13
|
||||
|
|
||||
LL | (x, y.0 > 2) if x != 0 => (),
|
||||
| ^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to the match arm guard
|
||||
|
|
||||
LL | (x, val) if x != 0 && val == (y.0 > 2) => (),
|
||||
| ~~~ +++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = y.0 > 2;
|
||||
LL ~ match (0, 0) {
|
||||
LL ~ (x, VAL) if x != 0 => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | (x, const { y.0 > 2 }) if x != 0 => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:70:13
|
||||
|
|
||||
LL | (x, y.0 > 2) if x != 0 || x != 1 => (),
|
||||
| ^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to the match arm guard
|
||||
|
|
||||
LL | (x, val) if (x != 0 || x != 1) && val == (y.0 > 2) => (),
|
||||
| ~~~ + +++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = y.0 > 2;
|
||||
LL ~ match (0, 0) {
|
||||
LL | (x, y.0 > 2) if x != 0 => (),
|
||||
LL ~ (x, VAL) if x != 0 || x != 1 => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | (x, const { y.0 > 2 }) if x != 0 || x != 1 => (),
|
||||
| +++++++ +
|
||||
|
||||
error: left-hand side of `@` must be a binding
|
||||
--> $DIR/recover-pat-exprs.rs:83:9
|
||||
|
|
||||
LL | x.sqrt() @ .. => (),
|
||||
| --------^^^--
|
||||
| | |
|
||||
| | also a pattern
|
||||
| interpreted as a pattern, not a binding
|
||||
|
|
||||
= note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`
|
||||
|
||||
error: expected one of `)`, `,`, or `|`, found `+`
|
||||
--> $DIR/recover-pat-exprs.rs:97:12
|
||||
|
|
||||
LL | (_ + 1) => (),
|
||||
| ^ expected one of `)`, `,`, or `|`
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:81:9
|
||||
|
|
||||
LL | u8::MAX.abs() => (),
|
||||
| ^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == u8::MAX.abs() => (),
|
||||
| ~~~ +++++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = u8::MAX.abs();
|
||||
LL ~ match u8::MAX {
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { u8::MAX.abs() } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:86:17
|
||||
|
|
||||
LL | z @ w @ v.u() => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | z @ w @ val if val == v.u() => (),
|
||||
| ~~~ +++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = v.u();
|
||||
LL ~ match u8::MAX {
|
||||
LL | u8::MAX.abs() => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ z @ w @ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | z @ w @ const { v.u() } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:88:9
|
||||
|
|
||||
LL | y.ilog(3) => (),
|
||||
| ^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == y.ilog(3) => (),
|
||||
| ~~~ +++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = y.ilog(3);
|
||||
LL ~ match u8::MAX {
|
||||
LL | u8::MAX.abs() => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { y.ilog(3) } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:90:9
|
||||
|
|
||||
LL | n + 1 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == n + 1 => (),
|
||||
| ~~~ +++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = n + 1;
|
||||
LL ~ match u8::MAX {
|
||||
LL | u8::MAX.abs() => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { n + 1 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:92:10
|
||||
|
|
||||
LL | ("".f() + 14 * 8) => (),
|
||||
| ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | (val) if val == "".f() + 14 * 8 => (),
|
||||
| ~~~ +++++++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = "".f() + 14 * 8;
|
||||
LL ~ match u8::MAX {
|
||||
LL | u8::MAX.abs() => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ (VAL) => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | (const { "".f() + 14 * 8 }) => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:95:9
|
||||
|
|
||||
LL | f?() => (),
|
||||
| ^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | val if val == f?() => (),
|
||||
| ~~~ ++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = f?();
|
||||
LL ~ match u8::MAX {
|
||||
LL | u8::MAX.abs() => (),
|
||||
...
|
||||
LL | 0 | ((1) | 2) | 3 => (),
|
||||
LL ~ VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { f?() } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:101:9
|
||||
|
|
||||
LL | let 1 + 1 = 2;
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected one of `)`, `,`, `@`, or `|`, found `*`
|
||||
--> $DIR/recover-pat-exprs.rs:104:28
|
||||
|
|
||||
LL | let b = matches!(x, (x * x | x.f()) | x[0]);
|
||||
| ^ expected one of `)`, `,`, `@`, or `|`
|
||||
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||
|
|
||||
= note: while parsing argument for this `pat` macro fragment
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:60:10
|
||||
|
|
||||
LL | (1 + 2) * 3 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:75:5
|
||||
|
|
||||
LL | 1 + 2 * PI.cos() => 2,
|
||||
| ^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:83:9
|
||||
|
|
||||
LL | x.sqrt() @ .. => (),
|
||||
| ^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: aborting due to 45 previous errors
|
||||
|
46
tests/ui/parser/recover/recover-pat-issues.rs
Normal file
46
tests/ui/parser/recover/recover-pat-issues.rs
Normal file
@ -0,0 +1,46 @@
|
||||
struct Foo(String);
|
||||
struct Bar { baz: String }
|
||||
|
||||
fn foo(foo: Foo) -> bool {
|
||||
match foo {
|
||||
Foo("hi".to_owned()) => true,
|
||||
//~^ error: expected a pattern, found an expression
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn bar(bar: Bar) -> bool {
|
||||
match bar {
|
||||
Bar { baz: "hi".to_owned() } => true,
|
||||
//~^ error: expected a pattern, found an expression
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
/// Issue #90121
|
||||
fn baz() {
|
||||
let foo = vec!["foo".to_string()];
|
||||
|
||||
match foo.as_slice() {
|
||||
&["foo".to_string()] => {}
|
||||
//~^ error: expected a pattern, found an expression
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
/// Issue #104996
|
||||
fn qux() {
|
||||
struct Magic(pub u16);
|
||||
const MAGIC: Magic = Magic(42);
|
||||
|
||||
if let Some(MAGIC.0 as usize) = None::<usize> {}
|
||||
//~^ error: expected a pattern, found an expression
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if let (-1.some(4)) = (0, Some(4)) {}
|
||||
//~^ error: expected a pattern, found an expression
|
||||
|
||||
if let (-1.Some(4)) = (0, Some(4)) {}
|
||||
//~^ error: expected a pattern, found an expression
|
||||
}
|
113
tests/ui/parser/recover/recover-pat-issues.stderr
Normal file
113
tests/ui/parser/recover/recover-pat-issues.stderr
Normal file
@ -0,0 +1,113 @@
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-issues.rs:6:13
|
||||
|
|
||||
LL | Foo("hi".to_owned()) => true,
|
||||
| ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | Foo(val) if val == "hi".to_owned() => true,
|
||||
| ~~~ +++++++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = "hi".to_owned();
|
||||
LL ~ match foo {
|
||||
LL ~ Foo(VAL) => true,
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | Foo(const { "hi".to_owned() }) => true,
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-issues.rs:14:20
|
||||
|
|
||||
LL | Bar { baz: "hi".to_owned() } => true,
|
||||
| ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | Bar { baz } if baz == "hi".to_owned() => true,
|
||||
| ~~~ +++++++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const BAZ: /* Type */ = "hi".to_owned();
|
||||
LL ~ match bar {
|
||||
LL ~ Bar { baz: BAZ } => true,
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | Bar { baz: const { "hi".to_owned() } } => true,
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-issues.rs:25:11
|
||||
|
|
||||
LL | &["foo".to_string()] => {}
|
||||
| ^^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider moving the expression to a match arm guard
|
||||
|
|
||||
LL | &[val] if val == "foo".to_string() => {}
|
||||
| ~~~ +++++++++++++++++++++++++++
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = "foo".to_string();
|
||||
LL ~ match foo.as_slice() {
|
||||
LL ~ &[VAL] => {}
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | &[const { "foo".to_string() }] => {}
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-issues.rs:36:17
|
||||
|
|
||||
LL | if let Some(MAGIC.0 as usize) = None::<usize> {}
|
||||
| ^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = MAGIC.0 as usize;
|
||||
LL ~ if let Some(VAL) = None::<usize> {}
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | if let Some(const { MAGIC.0 as usize }) = None::<usize> {}
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-issues.rs:41:13
|
||||
|
|
||||
LL | if let (-1.some(4)) = (0, Some(4)) {}
|
||||
| ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = -1.some(4);
|
||||
LL ~ if let (VAL) = (0, Some(4)) {}
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | if let (const { -1.some(4) }) = (0, Some(4)) {}
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-issues.rs:44:13
|
||||
|
|
||||
LL | if let (-1.Some(4)) = (0, Some(4)) {}
|
||||
| ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = -1.Some(4);
|
||||
LL ~ if let (VAL) = (0, Some(4)) {}
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | if let (const { -1.Some(4) }) = (0, Some(4)) {}
|
||||
| +++++++ +
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
20
tests/ui/parser/recover/recover-pat-lets.rs
Normal file
20
tests/ui/parser/recover/recover-pat-lets.rs
Normal file
@ -0,0 +1,20 @@
|
||||
fn main() {
|
||||
let x = Some(2);
|
||||
|
||||
let x.expect("foo");
|
||||
//~^ error: expected a pattern, found an expression
|
||||
|
||||
let x.unwrap(): u32;
|
||||
//~^ error: expected a pattern, found an expression
|
||||
|
||||
let x[0] = 1;
|
||||
//~^ error: expected a pattern, found an expression
|
||||
|
||||
let Some(1 + 1) = x else { //~ error: expected a pattern, found an expression
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(1 + 1) = x { //~ error: expected a pattern, found an expression
|
||||
return;
|
||||
}
|
||||
}
|
52
tests/ui/parser/recover/recover-pat-lets.stderr
Normal file
52
tests/ui/parser/recover/recover-pat-lets.stderr
Normal file
@ -0,0 +1,52 @@
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-lets.rs:4:9
|
||||
|
|
||||
LL | let x.expect("foo");
|
||||
| ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-lets.rs:7:9
|
||||
|
|
||||
LL | let x.unwrap(): u32;
|
||||
| ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-lets.rs:10:9
|
||||
|
|
||||
LL | let x[0] = 1;
|
||||
| ^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-lets.rs:13:14
|
||||
|
|
||||
LL | let Some(1 + 1) = x else {
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 1 + 1;
|
||||
LL ~ let Some(VAL) = x else {
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | let Some(const { 1 + 1 }) = x else {
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-lets.rs:17:17
|
||||
|
|
||||
LL | if let Some(1 + 1) = x {
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 1 + 1;
|
||||
LL ~ if let Some(VAL) = x {
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | if let Some(const { 1 + 1 }) = x {
|
||||
| +++++++ +
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
@ -22,8 +22,8 @@ fn main() {
|
||||
//~| warning: `...` range patterns are deprecated
|
||||
//~| warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
0.x()..="y".z() => (),
|
||||
//~^ error: expected a pattern range bound, found a method call
|
||||
//~| error: expected a pattern range bound, found a method call
|
||||
//~^ error: expected a pattern range bound, found an expression
|
||||
//~| error: expected a pattern range bound, found an expression
|
||||
};
|
||||
}
|
||||
|
216
tests/ui/parser/recover/recover-pat-ranges.stderr
Normal file
216
tests/ui/parser/recover/recover-pat-ranges.stderr
Normal file
@ -0,0 +1,216 @@
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:4:13
|
||||
|
|
||||
LL | 0..=(1) => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - 0..=(1) => (),
|
||||
LL + 0..=1 => (),
|
||||
|
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:6:9
|
||||
|
|
||||
LL | (-12)..=4 => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (-12)..=4 => (),
|
||||
LL + -12..=4 => (),
|
||||
|
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:8:9
|
||||
|
|
||||
LL | (0)..=(-4) => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (0)..=(-4) => (),
|
||||
LL + 0..=(-4) => (),
|
||||
|
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:8:15
|
||||
|
|
||||
LL | (0)..=(-4) => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (0)..=(-4) => (),
|
||||
LL + (0)..=-4 => (),
|
||||
|
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:13:9
|
||||
|
|
||||
LL | (4).. => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (4).. => (),
|
||||
LL + 4.. => (),
|
||||
|
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:15:9
|
||||
|
|
||||
LL | (-4 + 0).. => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (-4 + 0).. => (),
|
||||
LL + -4 + 0.. => (),
|
||||
|
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:18:9
|
||||
|
|
||||
LL | (1 + 4)...1 * 2 => (),
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - (1 + 4)...1 * 2 => (),
|
||||
LL + 1 + 4...1 * 2 => (),
|
||||
|
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/recover-pat-ranges.rs:11:12
|
||||
|
|
||||
LL | ..=1 + 2 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 1 + 2;
|
||||
LL ~ match -1 {
|
||||
LL | 0..=1 => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ ..=VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | ..=const { 1 + 2 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/recover-pat-ranges.rs:15:10
|
||||
|
|
||||
LL | (-4 + 0).. => (),
|
||||
| ^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = -4 + 0;
|
||||
LL ~ match -1 {
|
||||
LL | 0..=1 => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ (VAL).. => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | (const { -4 + 0 }).. => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/recover-pat-ranges.rs:18:10
|
||||
|
|
||||
LL | (1 + 4)...1 * 2 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 1 + 4;
|
||||
LL ~ match -1 {
|
||||
LL | 0..=1 => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ (VAL)...1 * 2 => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | (const { 1 + 4 })...1 * 2 => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/recover-pat-ranges.rs:18:19
|
||||
|
|
||||
LL | (1 + 4)...1 * 2 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 1 * 2;
|
||||
LL ~ match -1 {
|
||||
LL | 0..=1 => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ (1 + 4)...VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | (1 + 4)...const { 1 * 2 } => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/recover-pat-ranges.rs:24:9
|
||||
|
|
||||
LL | 0.x()..="y".z() => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 0.x();
|
||||
LL ~ match -1 {
|
||||
LL | 0..=1 => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ VAL..="y".z() => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | const { 0.x() }..="y".z() => (),
|
||||
| +++++++ +
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/recover-pat-ranges.rs:24:17
|
||||
|
|
||||
LL | 0.x()..="y".z() => (),
|
||||
| ^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = "y".z();
|
||||
LL ~ match -1 {
|
||||
LL | 0..=1 => (),
|
||||
...
|
||||
LL |
|
||||
LL ~ 0.x()..=VAL => (),
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | 0.x()..=const { "y".z() } => (),
|
||||
| +++++++ +
|
||||
|
||||
warning: `...` range patterns are deprecated
|
||||
--> $DIR/recover-pat-ranges.rs:18:16
|
||||
|
|
||||
LL | (1 + 4)...1 * 2 => (),
|
||||
| ^^^ help: use `..=` for an inclusive range
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(ellipsis_inclusive_range_patterns)]` on by default
|
||||
|
||||
error: aborting due to 13 previous errors; 1 warning emitted
|
||||
|
@ -1,35 +1,35 @@
|
||||
error: expected one of `=>`, `if`, or `|`, found `+`
|
||||
--> $DIR/pat-recover-wildcards.rs:5:11
|
||||
--> $DIR/recover-pat-wildcards.rs:5:11
|
||||
|
|
||||
LL | _ + 1 => ()
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: expected one of `)`, `,`, or `|`, found `%`
|
||||
--> $DIR/pat-recover-wildcards.rs:11:12
|
||||
--> $DIR/recover-pat-wildcards.rs:11:12
|
||||
|
|
||||
LL | (_ % 4) => ()
|
||||
| ^ expected one of `)`, `,`, or `|`
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `.`
|
||||
--> $DIR/pat-recover-wildcards.rs:17:10
|
||||
--> $DIR/recover-pat-wildcards.rs:17:10
|
||||
|
|
||||
LL | _.x() => ()
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `..=`
|
||||
--> $DIR/pat-recover-wildcards.rs:23:10
|
||||
--> $DIR/recover-pat-wildcards.rs:23:10
|
||||
|
|
||||
LL | _..=4 => ()
|
||||
| ^^^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
|
||||
--> $DIR/pat-recover-wildcards.rs:29:11
|
||||
--> $DIR/recover-pat-wildcards.rs:29:11
|
||||
|
|
||||
LL | .._ => ()
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/pat-recover-wildcards.rs:35:10
|
||||
--> $DIR/recover-pat-wildcards.rs:35:10
|
||||
|
|
||||
LL | 0..._ => ()
|
||||
| ^^^
|
||||
@ -42,31 +42,25 @@ LL + 0.._ => ()
|
||||
|
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
|
||||
--> $DIR/pat-recover-wildcards.rs:35:13
|
||||
--> $DIR/recover-pat-wildcards.rs:35:13
|
||||
|
|
||||
LL | 0..._ => ()
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: expected one of `)`, `,`, or `|`, found `*`
|
||||
--> $DIR/pat-recover-wildcards.rs:43:12
|
||||
--> $DIR/recover-pat-wildcards.rs:43:12
|
||||
|
|
||||
LL | (_ * 0)..5 => ()
|
||||
| ^ expected one of `)`, `,`, or `|`
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `(`
|
||||
--> $DIR/pat-recover-wildcards.rs:49:11
|
||||
--> $DIR/recover-pat-wildcards.rs:49:11
|
||||
|
|
||||
LL | ..(_) => ()
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/pat-recover-wildcards.rs:55:14
|
||||
|
|
||||
LL | 4..=(2 + _) => ()
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/pat-recover-wildcards.rs:55:13
|
||||
--> $DIR/recover-pat-wildcards.rs:55:13
|
||||
|
|
||||
LL | 4..=(2 + _) => ()
|
||||
| ^ ^
|
||||
@ -77,6 +71,23 @@ LL - 4..=(2 + _) => ()
|
||||
LL + 4..=2 + _ => ()
|
||||
|
|
||||
|
||||
error: expected a pattern range bound, found an expression
|
||||
--> $DIR/recover-pat-wildcards.rs:55:14
|
||||
|
|
||||
LL | 4..=(2 + _) => ()
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
|
||||
help: consider extracting the expression into a `const`
|
||||
|
|
||||
LL + const VAL: /* Type */ = 2 + _;
|
||||
LL ~ match 9 {
|
||||
LL ~ 4..=(VAL) => ()
|
||||
|
|
||||
help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
|
||||
|
|
||||
LL | 4..=(const { 2 + _ }) => ()
|
||||
| +++++++ +
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0586`.
|
Loading…
Reference in New Issue
Block a user