mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
Add suggestions for expressions in patterns
This commit is contained in:
parent
c2047219b5
commit
db09345ef6
@ -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 {
|
||||
|
@ -807,6 +807,14 @@ parse_unexpected_expr_in_pat =
|
||||
|
||||
.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,11 +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,
|
||||
/// 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)]
|
||||
|
@ -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,8 +23,8 @@ 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, DestructuredFloat};
|
||||
@ -448,12 +450,219 @@ impl<'a> Parser<'a> {
|
||||
|| self.token == token::CloseDelim(Delimiter::Parenthesis)
|
||||
&& self.look_ahead(1, Token::is_range_separator);
|
||||
|
||||
let span = expr.span;
|
||||
|
||||
Some((
|
||||
self.dcx().emit_err(UnexpectedExpressionInPattern { span: expr.span, is_bound }),
|
||||
expr.span,
|
||||
self.dcx()
|
||||
.create_err(UnexpectedExpressionInPattern {
|
||||
span,
|
||||
is_bound,
|
||||
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(),
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
/// allowed).
|
||||
fn parse_pat_with_range_pat(
|
||||
@ -845,7 +1054,7 @@ impl<'a> Parser<'a> {
|
||||
self.0 = true;
|
||||
*m = Mutability::Mut;
|
||||
}
|
||||
walk_pat(self, pat);
|
||||
mut_visit::walk_pat(self, pat);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
@ -53,13 +53,21 @@ fn type_cast() {
|
||||
}
|
||||
}
|
||||
|
||||
// ArithmeticOrLogicalExpression
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,30 +3,117 @@ error: expected a pattern, found an expression
|
||||
|
|
||||
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
|
||||
@ -63,12 +150,43 @@ error: expected a pattern, found an expression
|
||||
|
|
||||
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
|
||||
@ -102,99 +220,365 @@ error: expected a pattern, found an expression
|
||||
|
|
||||
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
|
||||
|
||||
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
|
||||
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:67:5
|
||||
--> $DIR/recover-pat-exprs.rs:63:9
|
||||
|
|
||||
LL | 1 + 2 * PI.cos() => 2,
|
||||
| ^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
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:73:9
|
||||
--> $DIR/recover-pat-exprs.rs:64:9
|
||||
|
|
||||
LL | u8::MAX.abs() => (),
|
||||
| ^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:75:9
|
||||
|
|
||||
LL | x.sqrt() @ .. => (),
|
||||
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:75:9
|
||||
--> $DIR/recover-pat-exprs.rs:83:9
|
||||
|
|
||||
LL | x.sqrt() @ .. => (),
|
||||
| --------^^^--
|
||||
@ -204,50 +588,161 @@ LL | x.sqrt() @ .. => (),
|
||||
|
|
||||
= note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:78:17
|
||||
|
|
||||
LL | z @ w @ v.u() => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:80:9
|
||||
|
|
||||
LL | y.ilog(3) => (),
|
||||
| ^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:82:9
|
||||
|
|
||||
LL | n + 1 => (),
|
||||
| ^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:84:10
|
||||
|
|
||||
LL | ("".f() + 14 * 8) => (),
|
||||
| ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected a pattern, found an expression
|
||||
--> $DIR/recover-pat-exprs.rs:87:9
|
||||
|
|
||||
LL | f?() => (),
|
||||
| ^^^^ arbitrary expressions are not allowed in patterns
|
||||
|
||||
error: expected one of `)`, `,`, or `|`, found `+`
|
||||
--> $DIR/recover-pat-exprs.rs:89:12
|
||||
--> $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:93:9
|
||||
--> $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:96:28
|
||||
--> $DIR/recover-pat-exprs.rs:104:28
|
||||
|
|
||||
LL | let b = matches!(x, (x * x | x.f()) | x[0]);
|
||||
| ^ expected one of `)`, `,`, `@`, or `|`
|
||||
@ -255,5 +750,23 @@ LL | let b = matches!(x, (x * x | x.f()) | x[0]);
|
||||
|
|
||||
= note: while parsing argument for this `pat` macro fragment
|
||||
|
||||
error: aborting due to 41 previous errors
|
||||
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
|
||||
|
||||
|
@ -3,36 +3,111 @@ error: expected a pattern, found an expression
|
||||
|
|
||||
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
|
||||
|
||||
|
@ -21,12 +21,32 @@ error: expected a pattern, found an expression
|
||||
|
|
||||
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
|
||||
|
||||
|
@ -46,12 +46,6 @@ LL - (0)..=(-4) => (),
|
||||
LL + (0)..=-4 => (),
|
||||
|
|
||||
|
||||
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
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:13:9
|
||||
|
|
||||
@ -64,12 +58,6 @@ LL - (4).. => (),
|
||||
LL + 4.. => (),
|
||||
|
|
||||
|
||||
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
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:15:9
|
||||
|
|
||||
@ -82,12 +70,6 @@ LL - (-4 + 0).. => (),
|
||||
LL + -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
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-ranges.rs:18:9
|
||||
|
|
||||
@ -100,23 +82,125 @@ 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
|
||||
|
@ -59,12 +59,6 @@ error: expected one of `=>`, `if`, or `|`, found `(`
|
||||
LL | ..(_) => ()
|
||||
| ^ expected one of `=>`, `if`, or `|`
|
||||
|
||||
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
|
||||
|
||||
error: range pattern bounds cannot have parentheses
|
||||
--> $DIR/recover-pat-wildcards.rs:55:13
|
||||
|
|
||||
@ -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