diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 10efe6fba6550..f32470d55b723 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -3,10 +3,6 @@ ast_lowering_abi_specified_multiple_times = .label = previously specified here .note = these ABIs are equivalent on the current target -ast_lowering_arbitrary_expression_in_pattern = - arbitrary expressions aren't allowed in patterns - .pattern_from_macro_note = the `expr` fragment specifier forces the metavariable's content to be an expression - ast_lowering_argument = argument ast_lowering_assoc_ty_binding_in_dyn = diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 02744d16b422f..628cd029e4589 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -363,15 +363,6 @@ pub struct NeverPatternWithGuard { pub span: Span, } -#[derive(Diagnostic)] -#[diag(ast_lowering_arbitrary_expression_in_pattern)] -pub struct ArbitraryExpressionInPattern { - #[primary_span] - pub span: Span, - #[note(ast_lowering_pattern_from_macro_note)] - pub pattern_from_macro_note: bool, -} - #[derive(Diagnostic)] #[diag(ast_lowering_inclusive_range_with_no_end)] pub struct InclusiveRangeWithNoEnd { diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 32de07a0755e2..7e43970640b60 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -1,6 +1,4 @@ -use super::errors::{ - ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding, -}; +use super::errors::{ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding}; use super::ResolverAstLoweringExt; use super::{ImplTraitContext, LoweringContext, ParamMode}; use crate::ImplTraitPosition; @@ -338,14 +336,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | ExprKind::Dummy => {} ExprKind::Path(..) if allow_paths => {} ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} - _ => { - let pattern_from_macro = expr.is_approximately_pattern(); - let guar = self.dcx().emit_err(ArbitraryExpressionInPattern { - span: expr.span, - pattern_from_macro_note: pattern_from_macro, - }); - return self.arena.alloc(self.expr_err(expr.span, guar)); - } + kind => panic!("unexpected expr kind {kind:?}"), } self.lower_expr(expr) } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 76d688edf0ca2..2296ccd621e4d 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2197,15 +2197,26 @@ impl<'a> Parser<'a> { /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). /// Keep this in sync with `Token::can_begin_literal_maybe_minus`. pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P> { - if let token::Interpolated(nt) = &self.token.kind { + let whole = if let token::Interpolated(nt) = &self.token.kind { match &**nt { - token::NtExpr(e) | token::NtLiteral(e) => { - let e = e.clone(); - self.bump(); - return Ok(e); - } - _ => {} - }; + token::NtLiteral(e) => Some(e.clone()), + token::NtExpr(e) => match &e.kind { + ExprKind::Lit(_) => Some(e.clone()), + ExprKind::Unary(UnOp::Neg, inner) + if matches!(&inner.kind, ast::ExprKind::Lit(_)) => + { + Some(e.clone()) + } + _ => None, + }, + _ => None, + } + } else { + None + }; + if let Some(e) = whole { + self.bump(); + return Ok(e); } let lo = self.token.span; diff --git a/tests/ui/issues/issue-43250.rs b/tests/ui/issues/issue-43250.rs index 24d70d2964bb2..f9228cd8a8a6b 100644 --- a/tests/ui/issues/issue-43250.rs +++ b/tests/ui/issues/issue-43250.rs @@ -4,10 +4,10 @@ fn main() { macro_rules! m { ($a:expr) => { let $a = 0; + //~^ ERROR expected pattern, found expression `y` + //~| ERROR expected pattern, found expression `C` } } m!(y); - //~^ ERROR arbitrary expressions aren't allowed in patterns m!(C); - //~^ ERROR arbitrary expressions aren't allowed in patterns } diff --git a/tests/ui/issues/issue-43250.stderr b/tests/ui/issues/issue-43250.stderr index e74342b85adb3..c09622887b706 100644 --- a/tests/ui/issues/issue-43250.stderr +++ b/tests/ui/issues/issue-43250.stderr @@ -1,18 +1,24 @@ -error: arbitrary expressions aren't allowed in patterns - --> $DIR/issue-43250.rs:9:8 +error: expected pattern, found expression `y` + --> $DIR/issue-43250.rs:6:17 | +LL | let $a = 0; + | ^^ expected pattern +... LL | m!(y); - | ^ + | ----- in this macro invocation | - = note: the `expr` fragment specifier forces the metavariable's content to be an expression + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error: arbitrary expressions aren't allowed in patterns - --> $DIR/issue-43250.rs:11:8 +error: expected pattern, found expression `C` + --> $DIR/issue-43250.rs:6:17 | +LL | let $a = 0; + | ^^ expected pattern +... LL | m!(C); - | ^ + | ----- in this macro invocation | - = note: the `expr` fragment specifier forces the metavariable's content to be an expression + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/lowering/expr-in-pat-issue-99380.rs b/tests/ui/lowering/expr-in-pat-issue-99380.rs index 1d4a047f717f7..f6d830cc1c9f5 100644 --- a/tests/ui/lowering/expr-in-pat-issue-99380.rs +++ b/tests/ui/lowering/expr-in-pat-issue-99380.rs @@ -1,11 +1,11 @@ macro_rules! foo { ($p:expr) => { - if let $p = Some(42) { + if let $p = Some(42) { //~ ERROR expected pattern, found expression `Some(3)` return; } }; } fn main() { - foo!(Some(3)); //~ ERROR arbitrary expressions aren't allowed in patterns + foo!(Some(3)); } diff --git a/tests/ui/lowering/expr-in-pat-issue-99380.stderr b/tests/ui/lowering/expr-in-pat-issue-99380.stderr index 29438c9b06360..fbe61bd08e4fb 100644 --- a/tests/ui/lowering/expr-in-pat-issue-99380.stderr +++ b/tests/ui/lowering/expr-in-pat-issue-99380.stderr @@ -1,10 +1,13 @@ -error: arbitrary expressions aren't allowed in patterns - --> $DIR/expr-in-pat-issue-99380.rs:10:10 +error: expected pattern, found expression `Some(3)` + --> $DIR/expr-in-pat-issue-99380.rs:3:16 | +LL | if let $p = Some(42) { + | ^^ expected pattern +... LL | foo!(Some(3)); - | ^^^^^^^ + | ------------- in this macro invocation | - = note: the `expr` fragment specifier forces the metavariable's content to be an expression + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/macros/trace_faulty_macros.rs b/tests/ui/macros/trace_faulty_macros.rs index 87036bb9c6f75..bef40e09e6f2f 100644 --- a/tests/ui/macros/trace_faulty_macros.rs +++ b/tests/ui/macros/trace_faulty_macros.rs @@ -43,10 +43,10 @@ fn use_bang_macro_as_attr() {} fn use_derive_macro_as_attr() {} macro_rules! test { - (let $p:pat = $e:expr) => {test!(($p,$e))}; + (let $p:pat = $e:expr) => {test!(($p,$e))}; //~ ERROR expected pattern, found expression `1+1` // this should be expr // vvv - (($p:pat, $e:pat)) => {let $p = $e;}; //~ ERROR expected expression, found pattern `1+1` + (($p:pat, $e:pat)) => {let $p = $e;}; } fn foo() { diff --git a/tests/ui/macros/trace_faulty_macros.stderr b/tests/ui/macros/trace_faulty_macros.stderr index 66d7b76bb0726..56cd9fe231b11 100644 --- a/tests/ui/macros/trace_faulty_macros.stderr +++ b/tests/ui/macros/trace_faulty_macros.stderr @@ -69,22 +69,18 @@ LL | #[derive(Debug)] LL | fn use_derive_macro_as_attr() {} | -------------------------------- not a `struct`, `enum` or `union` -error: expected expression, found pattern `1+1` - --> $DIR/trace_faulty_macros.rs:49:37 +error: expected pattern, found expression `1+1` + --> $DIR/trace_faulty_macros.rs:46:42 | LL | (let $p:pat = $e:expr) => {test!(($p,$e))}; - | -- this is interpreted as expression, but it is expected to be pattern + | ^^ expected pattern ... LL | (($p:pat, $e:pat)) => {let $p = $e;}; - | ^^ expected expression + | ------ while parsing argument for this `pat` macro fragment ... LL | test!(let x = 1+1); - | ------------------ - | | | - | | this is expected to be expression - | in this macro invocation + | ------------------ in this macro invocation | - = note: when forwarding a matched fragment to another macro-by-example, matchers in the second macro will see an opaque AST of the fragment type, not the underlying tokens = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) note: trace_macro @@ -107,7 +103,6 @@ LL | test!(let x = 1+1); = note: expanding `test! { let x = 1+1 }` = note: to `test! ((x, 1+1))` = note: expanding `test! { (x, 1+1) }` - = note: to `let x = 1+1;` error: aborting due to 5 previous errors diff --git a/tests/ui/macros/vec-macro-in-pattern.rs b/tests/ui/macros/vec-macro-in-pattern.rs index ce4298b8bb334..028628457a631 100644 --- a/tests/ui/macros/vec-macro-in-pattern.rs +++ b/tests/ui/macros/vec-macro-in-pattern.rs @@ -4,7 +4,7 @@ fn main() { match Some(vec![42]) { - Some(vec![43]) => {} //~ ERROR arbitrary expressions aren't allowed in patterns + Some(vec![43]) => {} //~ ERROR expected pattern, found expression _ => {} } } diff --git a/tests/ui/macros/vec-macro-in-pattern.stderr b/tests/ui/macros/vec-macro-in-pattern.stderr index 1a446b8c3edbc..a818d0a0981f7 100644 --- a/tests/ui/macros/vec-macro-in-pattern.stderr +++ b/tests/ui/macros/vec-macro-in-pattern.stderr @@ -1,11 +1,14 @@ -error: arbitrary expressions aren't allowed in patterns +error: expected pattern, found expression `< [_] > :: into_vec(#[rustc_box] $crate :: boxed :: Box :: new([43]))` --> $DIR/vec-macro-in-pattern.rs:7:14 | LL | Some(vec![43]) => {} | ^^^^^^^^ + | | + | expected pattern + | in this macro invocation + | this macro call doesn't expand to a pattern | - = note: the `expr` fragment specifier forces the metavariable's content to be an expression - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::__rust_force_expr` which comes from the expansion of the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/match/expr_before_ident_pat.rs b/tests/ui/match/expr_before_ident_pat.rs index 27ef3d05a2954..845ce5d1bd1bd 100644 --- a/tests/ui/match/expr_before_ident_pat.rs +++ b/tests/ui/match/expr_before_ident_pat.rs @@ -2,12 +2,11 @@ macro_rules! funny { ($a:expr, $b:ident) => { match [1, 2] { [$a, $b] => {} + //~^ ERROR expected pattern, found expression `a` } }; } fn main() { funny!(a, a); - //~^ ERROR cannot find value `a` in this scope - //~| ERROR arbitrary expressions aren't allowed in patterns } diff --git a/tests/ui/match/expr_before_ident_pat.stderr b/tests/ui/match/expr_before_ident_pat.stderr index 1657c51545cb2..817fe90478d07 100644 --- a/tests/ui/match/expr_before_ident_pat.stderr +++ b/tests/ui/match/expr_before_ident_pat.stderr @@ -1,17 +1,13 @@ -error[E0425]: cannot find value `a` in this scope - --> $DIR/expr_before_ident_pat.rs:10:12 +error: expected pattern, found expression `a` + --> $DIR/expr_before_ident_pat.rs:4:14 | +LL | [$a, $b] => {} + | ^^ expected pattern +... LL | funny!(a, a); - | ^ not found in this scope - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/expr_before_ident_pat.rs:10:12 - | -LL | funny!(a, a); - | ^ + | ------------ in this macro invocation | - = note: the `expr` fragment specifier forces the metavariable's content to be an expression + = note: this error originates in the macro `funny` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs index 30f3781bf7743..75361eea2e3aa 100644 --- a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs +++ b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs @@ -4,21 +4,20 @@ macro_rules! mac1 { ($eval:expr) => { let mut $eval = (); - //~^ ERROR `mut` must be followed by a named binding + //~^ ERROR expected identifier, found expression `does_not_exist!()` }; } macro_rules! mac2 { ($eval:pat) => { let mut $eval = (); - //~^ ERROR `mut` must be followed by a named binding - //~| ERROR expected identifier, found `does_not_exist!()` + //~^ ERROR expected identifier, found `does_not_exist!()` + //~| ERROR `mut` must be followed by a named binding }; } fn foo() { mac1! { does_not_exist!() } - //~^ ERROR cannot find macro `does_not_exist` in this scope mac2! { does_not_exist!() } //~^ ERROR cannot find macro `does_not_exist` in this scope } diff --git a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr index 2bd87ee0c38fa..4dde3968f9202 100644 --- a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr +++ b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr @@ -1,13 +1,12 @@ -error: `mut` must be followed by a named binding - --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:6:13 +error: expected identifier, found expression `does_not_exist!()` + --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:6:17 | LL | let mut $eval = (); - | ^^^^ help: remove the `mut` prefix + | ^^^^^ expected identifier ... LL | mac1! { does_not_exist!() } | --------------------------- in this macro invocation | - = note: `mut` may be followed by `variable` and `variable @ pattern` = note: this error originates in the macro `mac1` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected identifier, found `does_not_exist!()` @@ -34,16 +33,10 @@ LL | mac2! { does_not_exist!() } = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find macro `does_not_exist` in this scope - --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:22:13 + --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:21:13 | LL | mac2! { does_not_exist!() } | ^^^^^^^^^^^^^^ -error: cannot find macro `does_not_exist` in this scope - --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13 - | -LL | mac1! { does_not_exist!() } - | ^^^^^^^^^^^^^^ - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/pattern/issue-92074-macro-ice.rs b/tests/ui/pattern/issue-92074-macro-ice.rs index 039d3b314445d..98510696b5155 100644 --- a/tests/ui/pattern/issue-92074-macro-ice.rs +++ b/tests/ui/pattern/issue-92074-macro-ice.rs @@ -7,21 +7,19 @@ fn get_usize() -> usize { } macro_rules! force_expr { - ($e:expr) => { $e } + ($e:expr) => { $e } //~ ERROR expected pattern, found expression `Vec :: new()` } macro_rules! force_pat { - ($a:expr, $b:expr) => { $a..=$b } + ($a:expr, $b:expr) => { $a..=$b } //~ ERROR expected pattern, found expression `get_usize()` } macro_rules! make_vec { - () => { force_expr!(Vec::new()) } //~ ERROR arbitrary expressions aren't allowed + () => { force_expr!(Vec::new()) } } macro_rules! make_pat { () => { force_pat!(get_usize(), get_usize()) } - //~^ ERROR arbitrary expressions aren't allowed - //~| ERROR arbitrary expressions aren't allowed } #[allow(unreachable_code)] diff --git a/tests/ui/pattern/issue-92074-macro-ice.stderr b/tests/ui/pattern/issue-92074-macro-ice.stderr index 025592116e511..606e7384b7cef 100644 --- a/tests/ui/pattern/issue-92074-macro-ice.stderr +++ b/tests/ui/pattern/issue-92074-macro-ice.stderr @@ -1,38 +1,30 @@ -error: arbitrary expressions aren't allowed in patterns - --> $DIR/issue-92074-macro-ice.rs:18:25 +error: expected pattern, found expression `Vec :: new()` + --> $DIR/issue-92074-macro-ice.rs:10:20 | +LL | ($e:expr) => { $e } + | ^^ expected pattern +... LL | () => { force_expr!(Vec::new()) } - | ^^^^^^^^^^ + | ----------------------- this macro call doesn't expand to a pattern ... LL | assert!(matches!(x, En::A(make_vec!()))); | ----------- in this macro invocation | - = note: the `expr` fragment specifier forces the metavariable's content to be an expression - = note: this error originates in the macro `make_vec` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `force_expr` which comes from the expansion of the macro `make_vec` (in Nightly builds, run with -Z macro-backtrace for more info) -error: arbitrary expressions aren't allowed in patterns - --> $DIR/issue-92074-macro-ice.rs:22:24 +error: expected pattern, found expression `get_usize()` + --> $DIR/issue-92074-macro-ice.rs:14:29 | -LL | () => { force_pat!(get_usize(), get_usize()) } - | ^^^^^^^^^^^ +LL | ($a:expr, $b:expr) => { $a..=$b } + | ^^ expected pattern ... -LL | assert!(matches!(5, make_pat!())); - | ----------- in this macro invocation - | - = note: the `expr` fragment specifier forces the metavariable's content to be an expression - = note: this error originates in the macro `make_pat` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/issue-92074-macro-ice.rs:22:37 - | LL | () => { force_pat!(get_usize(), get_usize()) } - | ^^^^^^^^^^^ + | ------------------------------------ this macro call doesn't expand to a pattern ... LL | assert!(matches!(5, make_pat!())); | ----------- in this macro invocation | - = note: the `expr` fragment specifier forces the metavariable's content to be an expression - = note: this error originates in the macro `make_pat` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `force_pat` which comes from the expansion of the macro `make_pat` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/patkind-litrange-no-expr.rs b/tests/ui/pattern/patkind-litrange-no-expr.rs index 7ef541cb58528..43cf92a18b994 100644 --- a/tests/ui/pattern/patkind-litrange-no-expr.rs +++ b/tests/ui/pattern/patkind-litrange-no-expr.rs @@ -7,6 +7,7 @@ macro_rules! enum_number { fn foo(value: i32) -> Option<$name> { match value { $( $value => Some($name::$variant), )* // PatKind::Lit + //~^ ERROR expected pattern, found expression `1 + 1` $( $value ..= 42 => Some($name::$variant), )* // PatKind::Range _ => None } @@ -17,8 +18,7 @@ macro_rules! enum_number { enum_number!(Change { Pos = 1, Neg = -1, - Arith = 1 + 1, //~ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR arbitrary expressions aren't allowed in patterns + Arith = 1 + 1, }); fn main() {} diff --git a/tests/ui/pattern/patkind-litrange-no-expr.stderr b/tests/ui/pattern/patkind-litrange-no-expr.stderr index 45a2614894034..863ff2081ac23 100644 --- a/tests/ui/pattern/patkind-litrange-no-expr.stderr +++ b/tests/ui/pattern/patkind-litrange-no-expr.stderr @@ -1,16 +1,17 @@ -error: arbitrary expressions aren't allowed in patterns - --> $DIR/patkind-litrange-no-expr.rs:20:13 +error: expected pattern, found expression `1 + 1` + --> $DIR/patkind-litrange-no-expr.rs:9:20 | -LL | Arith = 1 + 1, - | ^^^^^ - -error: arbitrary expressions aren't allowed in patterns - --> $DIR/patkind-litrange-no-expr.rs:20:13 - | -LL | Arith = 1 + 1, - | ^^^^^ +LL | $( $value => Some($name::$variant), )* // PatKind::Lit + | ^^^^^^ expected pattern +... +LL | / enum_number!(Change { +LL | | Pos = 1, +LL | | Neg = -1, +LL | | Arith = 1 + 1, +LL | | }); + | |__- in this macro invocation | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: this error originates in the macro `enum_number` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: aborting due to 1 previous error