diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 396aac34515..be6f2c152a4 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -523,9 +523,18 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { "consider removing `for<...>`" ); gate_all!(more_qualified_paths, "usage of qualified paths in this context is experimental"); - for &span in spans.get(&sym::yield_expr).iter().copied().flatten() { - if !span.at_least_rust_2024() { - gate!(&visitor, coroutines, span, "yield syntax is experimental"); + // yield can be enabled either by `coroutines` or `gen_blocks` + if let Some(spans) = spans.get(&sym::yield_expr) { + for span in spans { + if (!visitor.features.coroutines() && !span.allows_unstable(sym::coroutines)) + && (!visitor.features.gen_blocks() && !span.allows_unstable(sym::gen_blocks)) + { + #[allow(rustc::untranslatable_diagnostic)] + // Don't know which of the two features to include in the + // error message, so I am arbitrarily picking one. + feature_err(&visitor.sess, sym::coroutines, *span, "yield syntax is experimental") + .emit(); + } } } gate_all!(gen_blocks, "gen blocks are experimental"); diff --git a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr index 3bb48e4a37a..032d7adf77a 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr +++ b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr @@ -8,6 +8,46 @@ LL | yield true; = 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[E0658]: yield syntax is experimental + --> $DIR/feature-gate-coroutines.rs:10:16 + | +LL | let _ = || yield true; + | ^^^^^^^^^^ + | + = 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[E0658]: yield syntax is experimental + --> $DIR/feature-gate-coroutines.rs:18:5 + | +LL | yield; + | ^^^^^ + | + = 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[E0658]: yield syntax is experimental + --> $DIR/feature-gate-coroutines.rs:19:5 + | +LL | yield 0; + | ^^^^^^^ + | + = 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[E0658]: yield syntax is experimental + --> $DIR/feature-gate-coroutines.rs:5:5 + | +LL | yield true; + | ^^^^^^^^^^ + | + = 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks --> $DIR/feature-gate-coroutines.rs:5:5 | @@ -46,7 +86,7 @@ error[E0627]: yield expression outside of coroutine literal LL | yield true; | ^^^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0627, E0658. For more information about an error, try `rustc --explain E0627`. diff --git a/tests/ui/feature-gates/feature-gate-coroutines.rs b/tests/ui/feature-gates/feature-gate-coroutines.rs index 28dce8596d3..a686357d910 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.rs +++ b/tests/ui/feature-gates/feature-gate-coroutines.rs @@ -4,17 +4,17 @@ fn main() { yield true; //~ ERROR yield syntax is experimental //~^ ERROR yield expression outside of coroutine literal - //[none]~^^ ERROR yield syntax is experimental + //~^^ ERROR yield syntax is experimental //~^^^ ERROR `yield` can only be used let _ = || yield true; //~ ERROR yield syntax is experimental - //[none]~^ ERROR yield syntax is experimental + //~^ ERROR yield syntax is experimental //~^^ ERROR `yield` can only be used } #[cfg(FALSE)] fn foo() { // Ok in 2024 edition - yield; //[none]~ ERROR yield syntax is experimental - yield 0; //[none]~ ERROR yield syntax is experimental + yield; //~ ERROR yield syntax is experimental + yield 0; //~ ERROR yield syntax is experimental }