From 57c5da8f1c1d36da3b69e98a75ed54efb4b45329 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Tue, 14 Jul 2020 07:53:23 +0000 Subject: [PATCH 1/3] Gate to if-let guard feature --- src/librustc_ast_passes/feature_gate.rs | 7 +- src/librustc_feature/active.rs | 4 + src/librustc_parse/parser/expr.rs | 14 +- src/librustc_span/symbol.rs | 1 + src/test/ui/parser/issue-15980.rs | 7 +- src/test/ui/parser/issue-15980.stderr | 25 +- .../ui/rfc-2294-if-let-guard/feature-gate.rs | 85 +++++ .../rfc-2294-if-let-guard/feature-gate.stderr | 327 ++++++++++++++++++ 8 files changed, 440 insertions(+), 30 deletions(-) create mode 100644 src/test/ui/rfc-2294-if-let-guard/feature-gate.rs create mode 100644 src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index ce39ceff8f3..95257f29a87 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -612,11 +612,14 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { let spans = sess.parse_sess.gated_spans.spans.borrow(); macro_rules! gate_all { ($gate:ident, $msg:literal) => { - for span in spans.get(&sym::$gate).unwrap_or(&vec![]) { - gate_feature_post!(&visitor, $gate, *span, $msg); + if let Some(spans) = spans.get(&sym::$gate) { + for span in spans { + gate_feature_post!(&visitor, $gate, *span, $msg); + } } }; } + gate_all!(if_let_guard, "`if let` guard is not implemented"); gate_all!(let_chains, "`let` expressions in this position are experimental"); gate_all!(async_closure, "async closures are unstable"); gate_all!(generators, "yield syntax is experimental"); diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 077f6cf3ca4..ced25961177 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -582,6 +582,9 @@ declare_features! ( /// The smallest useful subset of `const_generics`. (active, min_const_generics, "1.46.0", Some(74878), None), + /// Allows `if let` guard in match arms. + (active, if_let_guard, "1.47.0", Some(51114), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -591,6 +594,7 @@ declare_features! ( /// unanticipated results, such as compiler crashes. We warn the user about these /// to alert them. pub const INCOMPLETE_FEATURES: &[Symbol] = &[ + sym::if_let_guard, sym::impl_trait_in_bindings, sym::generic_associated_types, sym::const_generics, diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 3aec300d86d..564b017aab8 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1821,7 +1821,19 @@ impl<'a> Parser<'a> { let attrs = self.parse_outer_attributes()?; let lo = self.token.span; let pat = self.parse_top_pat(GateOr::No)?; - let guard = if self.eat_keyword(kw::If) { Some(self.parse_expr()?) } else { None }; + let guard = if self.eat_keyword(kw::If) { + let if_span = self.prev_token.span; + let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?; + if let ExprKind::Let(..) = cond.kind { + // Remove the last feature gating of a `let` expression since it's stable. + self.sess.gated_spans.ungate_last(sym::let_chains, cond.span); + let span = if_span.to(cond.span); + self.sess.gated_spans.gate(sym::if_let_guard, span); + } + Some(cond) + } else { + None + }; let arrow_span = self.token.span; self.expect(&token::FatArrow)?; let arm_start_span = self.token.span; diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 5203bfdb3b7..026f051f002 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -572,6 +572,7 @@ symbols! { i8, ident, if_let, + if_let_guard, if_while_or_patterns, ignore, impl_header_lifetime_elision, diff --git a/src/test/ui/parser/issue-15980.rs b/src/test/ui/parser/issue-15980.rs index 87faa7d5ff1..5392f87388c 100644 --- a/src/test/ui/parser/issue-15980.rs +++ b/src/test/ui/parser/issue-15980.rs @@ -4,14 +4,9 @@ fn main(){ let x: io::Result<()> = Ok(()); match x { Err(ref e) if e.kind == io::EndOfFile { - //~^ NOTE while parsing this struct + //~^ ERROR expected one of `!`, `.`, `::`, `=>`, `?`, or an operator, found `{` return - //~^ ERROR expected identifier, found keyword `return` - //~| NOTE expected identifier, found keyword } - //~^ NOTE expected one of `.`, `=>`, `?`, or an operator _ => {} - //~^ ERROR expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_` - //~| NOTE unexpected token } } diff --git a/src/test/ui/parser/issue-15980.stderr b/src/test/ui/parser/issue-15980.stderr index 5cefead2c74..3f6f015fd27 100644 --- a/src/test/ui/parser/issue-15980.stderr +++ b/src/test/ui/parser/issue-15980.stderr @@ -1,25 +1,8 @@ -error: expected identifier, found keyword `return` - --> $DIR/issue-15980.rs:8:13 +error: expected one of `!`, `.`, `::`, `=>`, `?`, or an operator, found `{` + --> $DIR/issue-15980.rs:6:47 | LL | Err(ref e) if e.kind == io::EndOfFile { - | ------------- while parsing this struct -LL | -LL | return - | ^^^^^^ expected identifier, found keyword - | -help: you can escape reserved keywords to use them as identifiers - | -LL | r#return - | + | ^ expected one of `!`, `.`, `::`, `=>`, `?`, or an operator -error: expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_` - --> $DIR/issue-15980.rs:13:9 - | -LL | } - | - expected one of `.`, `=>`, `?`, or an operator -LL | -LL | _ => {} - | ^ unexpected token - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs new file mode 100644 index 00000000000..c0a9bbc36b2 --- /dev/null +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs @@ -0,0 +1,85 @@ +// gate-test-if_let_guard + +use std::ops::Range; + +fn _if_let_guard() { + match () { + () if let 0 = 1 => {} + //~^ ERROR `if let` guard is not implemented + //~| ERROR `let` expressions are not supported here + + () if (let 0 = 1) => {} + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + + () if (((let 0 = 1))) => {} + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + + () if true && let 0 = 1 => {} + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + + () if let 0 = 1 && true => {} + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + + () if (let 0 = 1) && true => {} + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + + () if true && (let 0 = 1) => {} + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + + () if (let 0 = 1) && (let 0 = 1) => {} + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + + () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + + () if let Range { start: _, end: _ } = (true..true) && false => {} + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + _ => {} + } +} + +fn _macros() { + macro_rules! use_expr { + ($e:expr) => { + match () { + () if $e => {} + _ => {} + } + } + } + use_expr!((let 0 = 1 && 0 == 0)); + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + use_expr!((let 0 = 1)); + //~^ ERROR `let` expressions in this position are experimental + //~| ERROR `let` expressions are not supported here + match () { + #[cfg(FALSE)] + () if let 0 = 1 => {} + //~^ ERROR `if let` guard is not implemented + _ => {} + } + use_expr!(let 0 = 1); + //~^ ERROR no rules expected the token `let` +} + +fn main() {} diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr new file mode 100644 index 00000000000..5c7f8190dd6 --- /dev/null +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr @@ -0,0 +1,327 @@ +error: no rules expected the token `let` + --> $DIR/feature-gate.rs:81:15 + | +LL | macro_rules! use_expr { + | --------------------- when calling this macro +... +LL | use_expr!(let 0 = 1); + | ^^^ no rules expected this token in macro call + +error[E0658]: `if let` guard is not implemented + --> $DIR/feature-gate.rs:7:12 + | +LL | () if let 0 = 1 => {} + | ^^^^^^^^^^^^ + | + = note: see issue #51114 for more information + = help: add `#![feature(if_let_guard)]` to the crate attributes to enable + +error[E0658]: `if let` guard is not implemented + --> $DIR/feature-gate.rs:77:12 + | +LL | () if let 0 = 1 => {} + | ^^^^^^^^^^^^ + | + = note: see issue #51114 for more information + = help: add `#![feature(if_let_guard)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:11:16 + | +LL | () if (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:15:18 + | +LL | () if (((let 0 = 1))) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:19:23 + | +LL | () if true && let 0 = 1 => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:23:15 + | +LL | () if let 0 = 1 && true => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:27:16 + | +LL | () if (let 0 = 1) && true => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:31:24 + | +LL | () if true && (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:35:16 + | +LL | () if (let 0 = 1) && (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:35:31 + | +LL | () if (let 0 = 1) && (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:41:15 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:41:28 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:41:42 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:41:55 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:41:68 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:53:15 + | +LL | () if let Range { start: _, end: _ } = (true..true) && false => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:69:16 + | +LL | use_expr!((let 0 = 1 && 0 == 0)); + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0658]: `let` expressions in this position are experimental + --> $DIR/feature-gate.rs:72:16 + | +LL | use_expr!((let 0 = 1)); + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:7:15 + | +LL | () if let 0 = 1 => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:11:16 + | +LL | () if (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:15:18 + | +LL | () if (((let 0 = 1))) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:19:23 + | +LL | () if true && let 0 = 1 => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:23:15 + | +LL | () if let 0 = 1 && true => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:27:16 + | +LL | () if (let 0 = 1) && true => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:31:24 + | +LL | () if true && (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:35:16 + | +LL | () if (let 0 = 1) && (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:35:31 + | +LL | () if (let 0 = 1) && (let 0 = 1) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:41:15 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:41:28 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:41:42 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:41:55 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:41:68 + | +LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:53:15 + | +LL | () if let Range { start: _, end: _ } = (true..true) && false => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:69:16 + | +LL | use_expr!((let 0 = 1 && 0 == 0)); + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: `let` expressions are not supported here + --> $DIR/feature-gate.rs:72:16 + | +LL | use_expr!((let 0 = 1)); + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if`- and `while`-expressions + = note: as well as when nested within `&&` and parenthesis in those conditions + +error: aborting due to 36 previous errors + +For more information about this error, try `rustc --explain E0658`. From 0a8d4ce055d40bb4897d1cd5c110174ede8ed505 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 24 Jul 2020 16:24:15 +0000 Subject: [PATCH 2/3] Fallback to pase_expr because match guard accepts struct literals --- src/librustc_parse/parser/expr.rs | 2 +- src/test/ui/parser/issue-15980.rs | 7 ++++++- src/test/ui/parser/issue-15980.stderr | 25 +++++++++++++++++++++---- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 564b017aab8..6f03aea798c 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1823,7 +1823,7 @@ impl<'a> Parser<'a> { let pat = self.parse_top_pat(GateOr::No)?; let guard = if self.eat_keyword(kw::If) { let if_span = self.prev_token.span; - let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?; + let cond = self.parse_expr()?; if let ExprKind::Let(..) = cond.kind { // Remove the last feature gating of a `let` expression since it's stable. self.sess.gated_spans.ungate_last(sym::let_chains, cond.span); diff --git a/src/test/ui/parser/issue-15980.rs b/src/test/ui/parser/issue-15980.rs index 5392f87388c..87faa7d5ff1 100644 --- a/src/test/ui/parser/issue-15980.rs +++ b/src/test/ui/parser/issue-15980.rs @@ -4,9 +4,14 @@ fn main(){ let x: io::Result<()> = Ok(()); match x { Err(ref e) if e.kind == io::EndOfFile { - //~^ ERROR expected one of `!`, `.`, `::`, `=>`, `?`, or an operator, found `{` + //~^ NOTE while parsing this struct return + //~^ ERROR expected identifier, found keyword `return` + //~| NOTE expected identifier, found keyword } + //~^ NOTE expected one of `.`, `=>`, `?`, or an operator _ => {} + //~^ ERROR expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_` + //~| NOTE unexpected token } } diff --git a/src/test/ui/parser/issue-15980.stderr b/src/test/ui/parser/issue-15980.stderr index 3f6f015fd27..5cefead2c74 100644 --- a/src/test/ui/parser/issue-15980.stderr +++ b/src/test/ui/parser/issue-15980.stderr @@ -1,8 +1,25 @@ -error: expected one of `!`, `.`, `::`, `=>`, `?`, or an operator, found `{` - --> $DIR/issue-15980.rs:6:47 +error: expected identifier, found keyword `return` + --> $DIR/issue-15980.rs:8:13 | LL | Err(ref e) if e.kind == io::EndOfFile { - | ^ expected one of `!`, `.`, `::`, `=>`, `?`, or an operator + | ------------- while parsing this struct +LL | +LL | return + | ^^^^^^ expected identifier, found keyword + | +help: you can escape reserved keywords to use them as identifiers + | +LL | r#return + | -error: aborting due to previous error +error: expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_` + --> $DIR/issue-15980.rs:13:9 + | +LL | } + | - expected one of `.`, `=>`, `?`, or an operator +LL | +LL | _ => {} + | ^ unexpected token + +error: aborting due to 2 previous errors From ef50477c786016bf1712a34155d067b407e35cc0 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sat, 25 Jul 2020 01:14:10 +0000 Subject: [PATCH 3/3] Add a regression test for match guard Unlike if condition, match guard accepts struct literal. --- .../ui/parser/struct-literal-in-match-guard.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/test/ui/parser/struct-literal-in-match-guard.rs diff --git a/src/test/ui/parser/struct-literal-in-match-guard.rs b/src/test/ui/parser/struct-literal-in-match-guard.rs new file mode 100644 index 00000000000..bf0551b5c97 --- /dev/null +++ b/src/test/ui/parser/struct-literal-in-match-guard.rs @@ -0,0 +1,18 @@ +// check-pass + +// Unlike `if` condition, `match` guards accept struct literals. +// This is detected in . + +#[derive(PartialEq)] +struct Foo { + x: isize, +} + +fn foo(f: Foo) { + match () { + () if f == Foo { x: 42 } => {} + _ => {} + } +} + +fn main() {}