From db0c825d2c745fdf87edd501ebda222052f98771 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 19 Aug 2025 13:12:17 +0000 Subject: [PATCH] Gate static coroutines behind a parser feature --- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_parse/src/parser/expr.rs | 8 +++- .../ui/coroutine/static-closure-unexpanded.rs | 10 +++++ .../static-closure-unexpanded.stderr | 13 ++++++ tests/ui/static/static-closures.rs | 1 + tests/ui/static/static-closures.stderr | 15 ++++++- tests/ui/unpretty/exhaustive.expanded.stdout | 1 + tests/ui/unpretty/exhaustive.hir.stderr | 40 +++++++++---------- tests/ui/unpretty/exhaustive.hir.stdout | 1 + tests/ui/unpretty/exhaustive.rs | 1 + 10 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 tests/ui/coroutine/static-closure-unexpanded.rs create mode 100644 tests/ui/coroutine/static-closure-unexpanded.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index c7f41fc3cb122..6741b8c340e9b 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -525,6 +525,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(where_clause_attrs, "attributes in `where` clause are unstable"); gate_all!(super_let, "`super let` is experimental"); gate_all!(frontmatter, "frontmatters are experimental"); + gate_all!(coroutines, "coroutine syntax is experimental"); if !visitor.features.never_patterns() { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 3cedc86dc0dbe..4d84d48c94b62 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2401,8 +2401,12 @@ impl<'a> Parser<'a> { let constness = self.parse_closure_constness(); - let movability = - if self.eat_keyword(exp!(Static)) { Movability::Static } else { Movability::Movable }; + let movability = if self.eat_keyword(exp!(Static)) { + self.psess.gated_spans.gate(sym::coroutines, self.prev_token.span); + Movability::Static + } else { + Movability::Movable + }; let coroutine_kind = if self.token_uninterpolated_span().at_least_rust_2018() { self.parse_coroutine_kind(Case::Sensitive) diff --git a/tests/ui/coroutine/static-closure-unexpanded.rs b/tests/ui/coroutine/static-closure-unexpanded.rs new file mode 100644 index 0000000000000..7cf24774deda0 --- /dev/null +++ b/tests/ui/coroutine/static-closure-unexpanded.rs @@ -0,0 +1,10 @@ +// Tests that static closures are not stable in the parser grammar unless the +// coroutine feature is enabled. + +#[cfg(any())] +fn foo() { + let _ = static || {}; + //~^ ERROR coroutine syntax is experimental +} + +fn main() {} diff --git a/tests/ui/coroutine/static-closure-unexpanded.stderr b/tests/ui/coroutine/static-closure-unexpanded.stderr new file mode 100644 index 0000000000000..f08bafd368fb9 --- /dev/null +++ b/tests/ui/coroutine/static-closure-unexpanded.stderr @@ -0,0 +1,13 @@ +error[E0658]: coroutine syntax is experimental + --> $DIR/static-closure-unexpanded.rs:6:13 + | +LL | let _ = static || {}; + | ^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/static/static-closures.rs b/tests/ui/static/static-closures.rs index 1bd518d6ffece..e836f1b85ebac 100644 --- a/tests/ui/static/static-closures.rs +++ b/tests/ui/static/static-closures.rs @@ -1,4 +1,5 @@ fn main() { static || {}; //~^ ERROR closures cannot be static + //~| ERROR coroutine syntax is experimental } diff --git a/tests/ui/static/static-closures.stderr b/tests/ui/static/static-closures.stderr index b11c0b5a530c5..ecc961cc1e4ea 100644 --- a/tests/ui/static/static-closures.stderr +++ b/tests/ui/static/static-closures.stderr @@ -1,9 +1,20 @@ +error[E0658]: coroutine syntax is experimental + --> $DIR/static-closures.rs:2:5 + | +LL | static || {}; + | ^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0697]: closures cannot be static --> $DIR/static-closures.rs:2:5 | LL | static || {}; | ^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0697`. +Some errors have detailed explanations: E0658, E0697. +For more information about an error, try `rustc --explain E0658`. diff --git a/tests/ui/unpretty/exhaustive.expanded.stdout b/tests/ui/unpretty/exhaustive.expanded.stdout index 53ca3c8e39156..220e2263f0d4d 100644 --- a/tests/ui/unpretty/exhaustive.expanded.stdout +++ b/tests/ui/unpretty/exhaustive.expanded.stdout @@ -13,6 +13,7 @@ #![feature(box_patterns)] #![feature(builtin_syntax)] #![feature(const_trait_impl)] +#![feature(coroutines)] #![feature(decl_macro)] #![feature(deref_patterns)] #![feature(explicit_tail_calls)] diff --git a/tests/ui/unpretty/exhaustive.hir.stderr b/tests/ui/unpretty/exhaustive.hir.stderr index aa411ce81eb4c..eb5c186bd2c05 100644 --- a/tests/ui/unpretty/exhaustive.hir.stderr +++ b/tests/ui/unpretty/exhaustive.hir.stderr @@ -1,17 +1,17 @@ error[E0697]: closures cannot be static - --> $DIR/exhaustive.rs:209:9 + --> $DIR/exhaustive.rs:210:9 | LL | static || value; | ^^^^^^^^^ error[E0697]: closures cannot be static - --> $DIR/exhaustive.rs:210:9 + --> $DIR/exhaustive.rs:211:9 | LL | static move || value; | ^^^^^^^^^^^^^^ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/exhaustive.rs:239:13 + --> $DIR/exhaustive.rs:240:13 | LL | fn expr_await() { | --------------- this is not `async` @@ -20,19 +20,19 @@ LL | fut.await; | ^^^^^ only allowed inside `async` functions and blocks error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/exhaustive.rs:288:9 + --> $DIR/exhaustive.rs:289:9 | LL | _; | ^ `_` not allowed here error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:298:9 + --> $DIR/exhaustive.rs:299:9 | LL | x::(); | ^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:299:9 + --> $DIR/exhaustive.rs:300:9 | LL | x::(T, T) -> T; | ^^^^^^^^^^^^^^ only `Fn` traits may use parentheses @@ -44,31 +44,31 @@ LL + x:: -> T; | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:300:9 + --> $DIR/exhaustive.rs:301:9 | LL | crate::() -> ()::expressions::() -> ()::expr_path; | ^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:300:26 + --> $DIR/exhaustive.rs:301:26 | LL | crate::() -> ()::expressions::() -> ()::expr_path; | ^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:303:9 + --> $DIR/exhaustive.rs:304:9 | LL | core::()::marker::()::PhantomData; | ^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:303:19 + --> $DIR/exhaustive.rs:304:19 | LL | core::()::marker::()::PhantomData; | ^^^^^^^^^^ only `Fn` traits may use parentheses error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks - --> $DIR/exhaustive.rs:390:9 + --> $DIR/exhaustive.rs:391:9 | LL | yield; | ^^^^^ @@ -79,7 +79,7 @@ LL | #[coroutine] fn expr_yield() { | ++++++++++++ error[E0703]: invalid ABI: found `C++` - --> $DIR/exhaustive.rs:470:23 + --> $DIR/exhaustive.rs:471:23 | LL | unsafe extern "C++" {} | ^^^^^ invalid ABI @@ -87,7 +87,7 @@ LL | unsafe extern "C++" {} = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions error: `..` patterns are not allowed here - --> $DIR/exhaustive.rs:677:13 + --> $DIR/exhaustive.rs:678:13 | LL | let ..; | ^^ @@ -95,13 +95,13 @@ LL | let ..; = note: only allowed in tuple, tuple struct, and slice patterns error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:792:16 + --> $DIR/exhaustive.rs:793:16 | LL | let _: T() -> !; | ^^^^^^^^ only `Fn` traits may use parentheses error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:806:16 + --> $DIR/exhaustive.rs:807:16 | LL | let _: impl Send; | ^^^^^^^^^ @@ -112,7 +112,7 @@ LL | let _: impl Send; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:807:16 + --> $DIR/exhaustive.rs:808:16 | LL | let _: impl Send + 'static; | ^^^^^^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ LL | let _: impl Send + 'static; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:808:16 + --> $DIR/exhaustive.rs:809:16 | LL | let _: impl 'static + Send; | ^^^^^^^^^^^^^^^^^^^ @@ -134,7 +134,7 @@ LL | let _: impl 'static + Send; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:809:16 + --> $DIR/exhaustive.rs:810:16 | LL | let _: impl ?Sized; | ^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | let _: impl ?Sized; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:810:16 + --> $DIR/exhaustive.rs:811:16 | LL | let _: impl [const] Clone; | ^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL | let _: impl [const] Clone; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:811:16 + --> $DIR/exhaustive.rs:812:16 | LL | let _: impl for<'a> Send; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 2b8f3b21396be..57cf3d21a8e92 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -12,6 +12,7 @@ #![feature(box_patterns)] #![feature(builtin_syntax)] #![feature(const_trait_impl)] +#![feature(coroutines)] #![feature(decl_macro)] #![feature(deref_patterns)] #![feature(explicit_tail_calls)] diff --git a/tests/ui/unpretty/exhaustive.rs b/tests/ui/unpretty/exhaustive.rs index 5292ddad4f6b2..2b62ad245244c 100644 --- a/tests/ui/unpretty/exhaustive.rs +++ b/tests/ui/unpretty/exhaustive.rs @@ -12,6 +12,7 @@ #![feature(box_patterns)] #![feature(builtin_syntax)] #![feature(const_trait_impl)] +#![feature(coroutines)] #![feature(decl_macro)] #![feature(deref_patterns)] #![feature(explicit_tail_calls)]