diff options
| author | bors <bors@rust-lang.org> | 2021-01-12 02:56:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-01-12 02:56:51 +0000 |
| commit | 467f5e99a541db94235f0c173bdffc8aeb177522 (patch) | |
| tree | 49044dd7f4359e27a047f8bb6c3349dcc2e86e59 | |
| parent | 04064416644eba7351b1a457c1de27d28a750c95 (diff) | |
| parent | 5b475a46181cc4e8bfe2ac64f3724a5c485d6c5c (diff) | |
| download | rust-467f5e99a541db94235f0c173bdffc8aeb177522.tar.gz rust-467f5e99a541db94235f0c173bdffc8aeb177522.zip | |
Auto merge of #76580 - rokob:iss76011, r=estebank
Suggest async {} for async || {}
Fixes #76011
This adds support for adding help diagnostics to the feature gating checks and
then uses it for the async_closure gate to add the extra bit of help
information as described in the issue.
| -rw-r--r-- | compiler/rustc_ast_passes/src/feature_gate.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/async-await/feature-async-closure.stderr | 1 | ||||
| -rw-r--r-- | src/test/ui/parser/block-no-opening-brace.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/parser/block-no-opening-brace.stderr | 12 |
5 files changed, 34 insertions, 17 deletions
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 435f32535b6..d65bc820f8f 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -14,6 +14,17 @@ use rustc_span::Span; use tracing::debug; macro_rules! gate_feature_fn { + ($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{ + let (visitor, has_feature, span, name, explain, help) = + (&*$visitor, $has_feature, $span, $name, $explain, $help); + let has_feature: bool = has_feature(visitor.features); + debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature); + if !has_feature && !span.allows_unstable($name) { + feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain) + .help(help) + .emit(); + } + }}; ($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{ let (visitor, has_feature, span, name, explain) = (&*$visitor, $has_feature, $span, $name, $explain); @@ -27,6 +38,9 @@ macro_rules! gate_feature_fn { } macro_rules! gate_feature_post { + ($visitor: expr, $feature: ident, $span: expr, $explain: expr, $help: expr) => { + gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain, $help) + }; ($visitor: expr, $feature: ident, $span: expr, $explain: expr) => { gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain) }; @@ -597,6 +611,13 @@ 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, $help:literal) => { + if let Some(spans) = spans.get(&sym::$gate) { + for span in spans { + gate_feature_post!(&visitor, $gate, *span, $msg, $help); + } + } + }; ($gate:ident, $msg:literal) => { if let Some(spans) = spans.get(&sym::$gate) { for span in spans { @@ -607,7 +628,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { } gate_all!(if_let_guard, "`if let` guards are experimental"); gate_all!(let_chains, "`let` expressions in this position are experimental"); - gate_all!(async_closure, "async closures are unstable"); + gate_all!( + async_closure, + "async closures are unstable", + "to use an async block, remove the `||`: `async {`" + ); gate_all!(generators, "yield syntax is experimental"); gate_all!(or_patterns, "or-patterns syntax is experimental"); gate_all!(raw_ref_op, "raw address of syntax is experimental"); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index d11db74a3bd..f4332e4548a 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1599,10 +1599,6 @@ impl<'a> Parser<'a> { } else { Async::No }; - if let Async::Yes { span, .. } = asyncness { - // Feature-gate `async ||` closures. - self.sess.gated_spans.gate(sym::async_closure, span); - } let capture_clause = self.parse_capture_clause()?; let decl = self.parse_fn_block_decl()?; @@ -1619,6 +1615,11 @@ impl<'a> Parser<'a> { } }; + if let Async::Yes { span, .. } = asyncness { + // Feature-gate `async ||` closures. + self.sess.gated_spans.gate(sym::async_closure, span); + } + Ok(self.mk_expr( lo.to(body.span), ExprKind::Closure(capture_clause, asyncness, movability, decl, body, lo.to(decl_hi)), diff --git a/src/test/ui/async-await/feature-async-closure.stderr b/src/test/ui/async-await/feature-async-closure.stderr index ba851ba7d29..485a838b67f 100644 --- a/src/test/ui/async-await/feature-async-closure.stderr +++ b/src/test/ui/async-await/feature-async-closure.stderr @@ -6,6 +6,7 @@ LL | let _ = async || {}; | = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information = help: add `#![feature(async_closure)]` to the crate attributes to enable + = help: to use an async block, remove the `||`: `async {` error: aborting due to previous error diff --git a/src/test/ui/parser/block-no-opening-brace.rs b/src/test/ui/parser/block-no-opening-brace.rs index e4bb39f6836..8a6599488b1 100644 --- a/src/test/ui/parser/block-no-opening-brace.rs +++ b/src/test/ui/parser/block-no-opening-brace.rs @@ -26,6 +26,6 @@ fn f4() { } fn f5() { - async //~ ERROR async closures are unstable + async let x = 0; //~ ERROR expected one of `move`, `|`, or `||`, found keyword `let` } diff --git a/src/test/ui/parser/block-no-opening-brace.stderr b/src/test/ui/parser/block-no-opening-brace.stderr index a88e4ac44cf..e32c8bdc73a 100644 --- a/src/test/ui/parser/block-no-opening-brace.stderr +++ b/src/test/ui/parser/block-no-opening-brace.stderr @@ -39,15 +39,5 @@ LL | async LL | let x = 0; | ^^^ unexpected token -error[E0658]: async closures are unstable - --> $DIR/block-no-opening-brace.rs:29:5 - | -LL | async - | ^^^^^ - | - = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information - = help: add `#![feature(async_closure)]` to the crate attributes to enable - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0658`. |
