Skip to content

Commit 397f895

Browse files
committed
Auto merge of #126571 - nnethercote:less-maybe_whole-expr-2, r=<try>
Less `maybe_whole_expr`, take 2 I first tried this in #107550. I now think it's worth doing again, as a precursor to #1241414. r? `@petrochenkov`
2 parents e23ae72 + 74a18a0 commit 397f895

20 files changed

+132
-159
lines changed

compiler/rustc_ast_lowering/messages.ftl

-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ ast_lowering_abi_specified_multiple_times =
33
.label = previously specified here
44
.note = these ABIs are equivalent on the current target
55
6-
ast_lowering_arbitrary_expression_in_pattern =
7-
arbitrary expressions aren't allowed in patterns
8-
.pattern_from_macro_note = the `expr` fragment specifier forces the metavariable's content to be an expression
9-
106
ast_lowering_argument = argument
117
128
ast_lowering_assoc_ty_binding_in_dyn =

compiler/rustc_ast_lowering/src/errors.rs

-9
Original file line numberDiff line numberDiff line change
@@ -363,15 +363,6 @@ pub struct NeverPatternWithGuard {
363363
pub span: Span,
364364
}
365365

366-
#[derive(Diagnostic)]
367-
#[diag(ast_lowering_arbitrary_expression_in_pattern)]
368-
pub struct ArbitraryExpressionInPattern {
369-
#[primary_span]
370-
pub span: Span,
371-
#[note(ast_lowering_pattern_from_macro_note)]
372-
pub pattern_from_macro_note: bool,
373-
}
374-
375366
#[derive(Diagnostic)]
376367
#[diag(ast_lowering_inclusive_range_with_no_end)]
377368
pub struct InclusiveRangeWithNoEnd {

compiler/rustc_ast_lowering/src/pat.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use super::errors::{
2-
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
3-
};
1+
use super::errors::{ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding};
42
use super::ResolverAstLoweringExt;
53
use super::{ImplTraitContext, LoweringContext, ParamMode};
64
use crate::ImplTraitPosition;
@@ -338,14 +336,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
338336
| ExprKind::Dummy => {}
339337
ExprKind::Path(..) if allow_paths => {}
340338
ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
341-
_ => {
342-
let pattern_from_macro = expr.is_approximately_pattern();
343-
let guar = self.dcx().emit_err(ArbitraryExpressionInPattern {
344-
span: expr.span,
345-
pattern_from_macro_note: pattern_from_macro,
346-
});
347-
return self.arena.alloc(self.expr_err(expr.span, guar));
348-
}
339+
kind => panic!("unexpected expr kind {kind:?}"),
349340
}
350341
self.lower_expr(expr)
351342
}

compiler/rustc_parse/src/parser/expr.rs

+42-32
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,6 @@ use rustc_span::{BytePos, ErrorGuaranteed, Pos, Span};
3838
use thin_vec::{thin_vec, ThinVec};
3939
use tracing::instrument;
4040

41-
/// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
42-
/// dropped into the token stream, which happens while parsing the result of
43-
/// macro expansion). Placement of these is not as complex as I feared it would
44-
/// be. The important thing is to make sure that lookahead doesn't balk at
45-
/// `token::Interpolated` tokens.
46-
macro_rules! maybe_whole_expr {
47-
($p:expr) => {
48-
if let token::Interpolated(nt) = &$p.token.kind {
49-
match &**nt {
50-
token::NtExpr(e) | token::NtLiteral(e) => {
51-
let e = e.clone();
52-
$p.bump();
53-
return Ok(e);
54-
}
55-
token::NtPath(path) => {
56-
let path = (**path).clone();
57-
$p.bump();
58-
return Ok($p.mk_expr($p.prev_token.span, ExprKind::Path(None, path)));
59-
}
60-
token::NtBlock(block) => {
61-
let block = block.clone();
62-
$p.bump();
63-
return Ok($p.mk_expr($p.prev_token.span, ExprKind::Block(block, None)));
64-
}
65-
_ => {}
66-
};
67-
}
68-
};
69-
}
70-
7141
#[derive(Debug)]
7242
pub(super) enum LhsExpr {
7343
NotYetParsed,
@@ -1438,7 +1408,27 @@ impl<'a> Parser<'a> {
14381408
/// correctly if called from `parse_dot_or_call_expr()`.
14391409
fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> {
14401410
maybe_recover_from_interpolated_ty_qpath!(self, true);
1441-
maybe_whole_expr!(self);
1411+
1412+
if let token::Interpolated(nt) = &self.token.kind {
1413+
match &**nt {
1414+
token::NtExpr(e) | token::NtLiteral(e) => {
1415+
let e = e.clone();
1416+
self.bump();
1417+
return Ok(e);
1418+
}
1419+
token::NtPath(path) => {
1420+
let path = (**path).clone();
1421+
self.bump();
1422+
return Ok(self.mk_expr(self.prev_token.span, ExprKind::Path(None, path)));
1423+
}
1424+
token::NtBlock(block) => {
1425+
let block = block.clone();
1426+
self.bump();
1427+
return Ok(self.mk_expr(self.prev_token.span, ExprKind::Block(block, None)));
1428+
}
1429+
_ => {}
1430+
};
1431+
}
14421432

14431433
// Outer attributes are already parsed and will be
14441434
// added to the return value after the fact.
@@ -2207,7 +2197,27 @@ impl<'a> Parser<'a> {
22072197
/// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
22082198
/// Keep this in sync with `Token::can_begin_literal_maybe_minus`.
22092199
pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
2210-
maybe_whole_expr!(self);
2200+
let whole = if let token::Interpolated(nt) = &self.token.kind {
2201+
match &**nt {
2202+
token::NtLiteral(e) => Some(e.clone()),
2203+
token::NtExpr(e) => match &e.kind {
2204+
ExprKind::Lit(_) => Some(e.clone()),
2205+
ExprKind::Unary(UnOp::Neg, inner)
2206+
if matches!(&inner.kind, ast::ExprKind::Lit(_)) =>
2207+
{
2208+
Some(e.clone())
2209+
}
2210+
_ => None,
2211+
},
2212+
_ => None,
2213+
}
2214+
} else {
2215+
None
2216+
};
2217+
if let Some(e) = whole {
2218+
self.bump();
2219+
return Ok(e);
2220+
}
22112221

22122222
let lo = self.token.span;
22132223
let minus_present = self.eat(&token::BinOp(token::Minus));

tests/ui/issues/issue-43250.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ fn main() {
44
macro_rules! m {
55
($a:expr) => {
66
let $a = 0;
7+
//~^ ERROR expected pattern, found expression `y`
8+
//~| ERROR expected pattern, found expression `C`
79
}
810
}
911
m!(y);
10-
//~^ ERROR arbitrary expressions aren't allowed in patterns
1112
m!(C);
12-
//~^ ERROR arbitrary expressions aren't allowed in patterns
1313
}

tests/ui/issues/issue-43250.stderr

+14-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1-
error: arbitrary expressions aren't allowed in patterns
2-
--> $DIR/issue-43250.rs:9:8
1+
error: expected pattern, found expression `y`
2+
--> $DIR/issue-43250.rs:6:17
33
|
4+
LL | let $a = 0;
5+
| ^^ expected pattern
6+
...
47
LL | m!(y);
5-
| ^
8+
| ----- in this macro invocation
69
|
7-
= note: the `expr` fragment specifier forces the metavariable's content to be an expression
10+
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
811

9-
error: arbitrary expressions aren't allowed in patterns
10-
--> $DIR/issue-43250.rs:11:8
12+
error: expected pattern, found expression `C`
13+
--> $DIR/issue-43250.rs:6:17
1114
|
15+
LL | let $a = 0;
16+
| ^^ expected pattern
17+
...
1218
LL | m!(C);
13-
| ^
19+
| ----- in this macro invocation
1420
|
15-
= note: the `expr` fragment specifier forces the metavariable's content to be an expression
21+
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
1622

1723
error: aborting due to 2 previous errors
1824

Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
macro_rules! foo {
22
($p:expr) => {
3-
if let $p = Some(42) {
3+
if let $p = Some(42) { //~ ERROR expected pattern, found expression `Some(3)`
44
return;
55
}
66
};
77
}
88

99
fn main() {
10-
foo!(Some(3)); //~ ERROR arbitrary expressions aren't allowed in patterns
10+
foo!(Some(3));
1111
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
error: arbitrary expressions aren't allowed in patterns
2-
--> $DIR/expr-in-pat-issue-99380.rs:10:10
1+
error: expected pattern, found expression `Some(3)`
2+
--> $DIR/expr-in-pat-issue-99380.rs:3:16
33
|
4+
LL | if let $p = Some(42) {
5+
| ^^ expected pattern
6+
...
47
LL | foo!(Some(3));
5-
| ^^^^^^^
8+
| ------------- in this macro invocation
69
|
7-
= note: the `expr` fragment specifier forces the metavariable's content to be an expression
10+
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
811

912
error: aborting due to 1 previous error
1013

tests/ui/macros/trace_faulty_macros.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ fn use_bang_macro_as_attr() {}
4343
fn use_derive_macro_as_attr() {}
4444

4545
macro_rules! test {
46-
(let $p:pat = $e:expr) => {test!(($p,$e))};
46+
(let $p:pat = $e:expr) => {test!(($p,$e))}; //~ ERROR expected pattern, found expression `1+1`
4747
// this should be expr
4848
// vvv
49-
(($p:pat, $e:pat)) => {let $p = $e;}; //~ ERROR expected expression, found pattern `1+1`
49+
(($p:pat, $e:pat)) => {let $p = $e;};
5050
}
5151

5252
fn foo() {

tests/ui/macros/trace_faulty_macros.stderr

+5-10
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,18 @@ LL | #[derive(Debug)]
6969
LL | fn use_derive_macro_as_attr() {}
7070
| -------------------------------- not a `struct`, `enum` or `union`
7171

72-
error: expected expression, found pattern `1+1`
73-
--> $DIR/trace_faulty_macros.rs:49:37
72+
error: expected pattern, found expression `1+1`
73+
--> $DIR/trace_faulty_macros.rs:46:42
7474
|
7575
LL | (let $p:pat = $e:expr) => {test!(($p,$e))};
76-
| -- this is interpreted as expression, but it is expected to be pattern
76+
| ^^ expected pattern
7777
...
7878
LL | (($p:pat, $e:pat)) => {let $p = $e;};
79-
| ^^ expected expression
79+
| ------ while parsing argument for this `pat` macro fragment
8080
...
8181
LL | test!(let x = 1+1);
82-
| ------------------
83-
| | |
84-
| | this is expected to be expression
85-
| in this macro invocation
82+
| ------------------ in this macro invocation
8683
|
87-
= 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
8884
= note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
8985

9086
note: trace_macro
@@ -107,7 +103,6 @@ LL | test!(let x = 1+1);
107103
= note: expanding `test! { let x = 1+1 }`
108104
= note: to `test! ((x, 1+1))`
109105
= note: expanding `test! { (x, 1+1) }`
110-
= note: to `let x = 1+1;`
111106

112107
error: aborting due to 5 previous errors
113108

tests/ui/macros/vec-macro-in-pattern.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
fn main() {
66
match Some(vec![42]) {
7-
Some(vec![43]) => {} //~ ERROR arbitrary expressions aren't allowed in patterns
7+
Some(vec![43]) => {} //~ ERROR expected pattern, found expression
88
_ => {}
99
}
1010
}
+6-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
error: arbitrary expressions aren't allowed in patterns
1+
error: expected pattern, found expression `< [_] > :: into_vec(#[rustc_box] $crate :: boxed :: Box :: new([43]))`
22
--> $DIR/vec-macro-in-pattern.rs:7:14
33
|
44
LL | Some(vec![43]) => {}
55
| ^^^^^^^^
6+
| |
7+
| expected pattern
8+
| in this macro invocation
9+
| this macro call doesn't expand to a pattern
610
|
7-
= note: the `expr` fragment specifier forces the metavariable's content to be an expression
8-
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
11+
= 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)
912

1013
error: aborting due to 1 previous error
1114

tests/ui/match/expr_before_ident_pat.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ macro_rules! funny {
22
($a:expr, $b:ident) => {
33
match [1, 2] {
44
[$a, $b] => {}
5+
//~^ ERROR expected pattern, found expression `a`
56
}
67
};
78
}
89

910
fn main() {
1011
funny!(a, a);
11-
//~^ ERROR cannot find value `a` in this scope
12-
//~| ERROR arbitrary expressions aren't allowed in patterns
1312
}
+8-12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
1-
error[E0425]: cannot find value `a` in this scope
2-
--> $DIR/expr_before_ident_pat.rs:10:12
1+
error: expected pattern, found expression `a`
2+
--> $DIR/expr_before_ident_pat.rs:4:14
33
|
4+
LL | [$a, $b] => {}
5+
| ^^ expected pattern
6+
...
47
LL | funny!(a, a);
5-
| ^ not found in this scope
6-
7-
error: arbitrary expressions aren't allowed in patterns
8-
--> $DIR/expr_before_ident_pat.rs:10:12
9-
|
10-
LL | funny!(a, a);
11-
| ^
8+
| ------------ in this macro invocation
129
|
13-
= note: the `expr` fragment specifier forces the metavariable's content to be an expression
10+
= note: this error originates in the macro `funny` (in Nightly builds, run with -Z macro-backtrace for more info)
1411

15-
error: aborting due to 2 previous errors
12+
error: aborting due to 1 previous error
1613

17-
For more information about this error, try `rustc --explain E0425`.

tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,20 @@
44
macro_rules! mac1 {
55
($eval:expr) => {
66
let mut $eval = ();
7-
//~^ ERROR `mut` must be followed by a named binding
7+
//~^ ERROR expected identifier, found expression `does_not_exist!()`
88
};
99
}
1010

1111
macro_rules! mac2 {
1212
($eval:pat) => {
1313
let mut $eval = ();
14-
//~^ ERROR `mut` must be followed by a named binding
15-
//~| ERROR expected identifier, found `does_not_exist!()`
14+
//~^ ERROR expected identifier, found `does_not_exist!()`
15+
//~| ERROR `mut` must be followed by a named binding
1616
};
1717
}
1818

1919
fn foo() {
2020
mac1! { does_not_exist!() }
21-
//~^ ERROR cannot find macro `does_not_exist` in this scope
2221
mac2! { does_not_exist!() }
2322
//~^ ERROR cannot find macro `does_not_exist` in this scope
2423
}

0 commit comments

Comments
 (0)