Skip to content

Commit 74a18a0

Browse files
committed
Be more picky in parse_literal_maybe_minus.
By only accepting `NtExpr` if it's a literal (possibly with a unary minus). This means various error cases are caught during parsing, instead of during HIR lowering, and the `ArbitraryExpressionInPattern` error is no longer needed.
1 parent 494db01 commit 74a18a0

20 files changed

+109
-135
lines changed

compiler/rustc_ast_lowering/messages.ftl

Lines changed: 0 additions & 4 deletions
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

Lines changed: 0 additions & 9 deletions
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

Lines changed: 2 additions & 11 deletions
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

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2197,15 +2197,26 @@ impl<'a> Parser<'a> {
21972197
/// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
21982198
/// Keep this in sync with `Token::can_begin_literal_maybe_minus`.
21992199
pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
2200-
if let token::Interpolated(nt) = &self.token.kind {
2200+
let whole = if let token::Interpolated(nt) = &self.token.kind {
22012201
match &**nt {
2202-
token::NtExpr(e) | token::NtLiteral(e) => {
2203-
let e = e.clone();
2204-
self.bump();
2205-
return Ok(e);
2206-
}
2207-
_ => {}
2208-
};
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);
22092220
}
22102221

22112222
let lo = self.token.span;

tests/ui/issues/issue-43250.rs

Lines changed: 2 additions & 2 deletions
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

Lines changed: 14 additions & 8 deletions
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

Lines changed: 2 additions & 2 deletions
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
}
Lines changed: 7 additions & 4 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 5 additions & 10 deletions
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

0 commit comments

Comments
 (0)