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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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, T> -> 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)]
