diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 34532967d9e..a1bd2679137 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -554,7 +554,12 @@ 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"); - gate_all!(coroutines, "yield syntax is experimental"); + for &span in spans.get(&sym::yield_expr).iter().copied().flatten() { + if !span.at_least_rust_2024() { + gate_feature_post!(&visitor, coroutines, span, "yield syntax is experimental"); + } + } + gate_all!(gen_blocks, "gen blocks are experimental"); gate_all!(raw_ref_op, "raw address of syntax is experimental"); gate_all!(const_trait_impl, "const trait impls are experimental"); gate_all!( diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 695de54eefa..72100863bb5 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -456,6 +456,8 @@ declare_features! ( (unstable, ffi_returns_twice, "1.34.0", Some(58314), None), /// Allows using `#[repr(align(...))]` on function items (unstable, fn_align, "1.53.0", Some(82232), None), + /// Allows defining gen blocks and `gen fn`. + (unstable, gen_blocks, "CURRENT_RUSTC_VERSION", Some(117078), None), /// Infer generic args for both consts and types. (unstable, generic_arg_infer, "1.55.0", Some(85077), None), /// An extension to the `generic_associated_types` feature, allowing incomplete features. diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a1b04105a4c..c6c7f025418 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1850,7 +1850,7 @@ impl<'a> Parser<'a> { let lo = self.prev_token.span; let kind = ExprKind::Yield(self.parse_expr_opt()?); let span = lo.to(self.prev_token.span); - self.sess.gated_spans.gate(sym::coroutines, span); + self.sess.gated_spans.gate(sym::yield_expr, span); let expr = self.mk_expr(span, kind); self.maybe_recover_from_bad_qpath(expr) } @@ -3075,6 +3075,7 @@ impl<'a> Parser<'a> { GenBlockKind::Async } else { assert!(self.eat_keyword(kw::Gen)); + self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.token.span)); GenBlockKind::Gen }; let capture_clause = self.parse_capture_clause()?; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 0d21c19e519..ba362c05965 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -819,6 +819,7 @@ symbols! { future_trait, gdb_script_file, ge, + gen_blocks, gen_future, gen_kill, generator_clone, @@ -1780,6 +1781,7 @@ symbols! { xmm_reg, yeet_desugar_details, yeet_expr, + yield_expr, ymm_reg, zmm_reg, } diff --git a/tests/ui/coroutine/gen_block.rs b/tests/ui/coroutine/gen_block.rs index fa502768236..c09fa2ae9be 100644 --- a/tests/ui/coroutine/gen_block.rs +++ b/tests/ui/coroutine/gen_block.rs @@ -1,6 +1,6 @@ // revisions: e2024 none //[e2024] compile-flags: --edition 2024 -Zunstable-options -#![cfg_attr(e2024, feature(coroutines))] +#![cfg_attr(e2024, feature(gen_blocks))] fn main() { let x = gen {}; diff --git a/tests/ui/coroutine/gen_block_is_coro.rs b/tests/ui/coroutine/gen_block_is_coro.rs index 814d5843a1b..c66ccefba85 100644 --- a/tests/ui/coroutine/gen_block_is_coro.rs +++ b/tests/ui/coroutine/gen_block_is_coro.rs @@ -1,5 +1,5 @@ //compile-flags: --edition 2024 -Zunstable-options -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, gen_blocks)] use std::ops::Coroutine; diff --git a/tests/ui/coroutine/gen_block_is_iter.rs b/tests/ui/coroutine/gen_block_is_iter.rs index 16d5813c69d..92625cf7c28 100644 --- a/tests/ui/coroutine/gen_block_is_iter.rs +++ b/tests/ui/coroutine/gen_block_is_iter.rs @@ -2,7 +2,7 @@ //compile-flags: --edition 2024 -Zunstable-options //[next] compile-flags: -Ztrait-solver=next // check-pass -#![feature(coroutines)] +#![feature(gen_blocks)] fn foo() -> impl Iterator { gen { yield 42 } diff --git a/tests/ui/coroutine/gen_block_is_no_future.rs b/tests/ui/coroutine/gen_block_is_no_future.rs index 8927544a7b9..94766519738 100644 --- a/tests/ui/coroutine/gen_block_is_no_future.rs +++ b/tests/ui/coroutine/gen_block_is_no_future.rs @@ -1,5 +1,5 @@ //compile-flags: --edition 2024 -Zunstable-options -#![feature(coroutines)] +#![feature(gen_blocks)] fn foo() -> impl std::future::Future { //~ ERROR is not a future gen { yield 42 } diff --git a/tests/ui/coroutine/gen_block_iterate.rs b/tests/ui/coroutine/gen_block_iterate.rs index 26932723779..04c44d58e52 100644 --- a/tests/ui/coroutine/gen_block_iterate.rs +++ b/tests/ui/coroutine/gen_block_iterate.rs @@ -2,7 +2,7 @@ //compile-flags: --edition 2024 -Zunstable-options //[next] compile-flags: -Ztrait-solver=next // run-pass -#![feature(coroutines)] +#![feature(gen_blocks)] fn foo() -> impl Iterator { gen { yield 42; for x in 3..6 { yield x } } diff --git a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr new file mode 100644 index 00000000000..595b42176b1 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr @@ -0,0 +1,9 @@ +error[E0627]: yield expression outside of coroutine literal + --> $DIR/feature-gate-coroutines.rs:5:5 + | +LL | yield true; + | ^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0627`. diff --git a/tests/ui/feature-gates/feature-gate-coroutines.stderr b/tests/ui/feature-gates/feature-gate-coroutines.none.stderr similarity index 65% rename from tests/ui/feature-gates/feature-gate-coroutines.stderr rename to tests/ui/feature-gates/feature-gate-coroutines.none.stderr index dd561643901..680bd1f2878 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.stderr +++ b/tests/ui/feature-gates/feature-gate-coroutines.none.stderr @@ -1,5 +1,5 @@ error[E0658]: yield syntax is experimental - --> $DIR/feature-gate-coroutines.rs:2:5 + --> $DIR/feature-gate-coroutines.rs:5:5 | LL | yield true; | ^^^^^^^^^^ @@ -8,7 +8,16 @@ LL | yield true; = help: add `#![feature(coroutines)]` to the crate attributes to enable error[E0658]: yield syntax is experimental - --> $DIR/feature-gate-coroutines.rs:8:5 + --> $DIR/feature-gate-coroutines.rs:8:16 + | +LL | let _ = || yield true; + | ^^^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + +error[E0658]: yield syntax is experimental + --> $DIR/feature-gate-coroutines.rs:14:5 | LL | yield; | ^^^^^ @@ -17,7 +26,7 @@ LL | yield; = help: add `#![feature(coroutines)]` to the crate attributes to enable error[E0658]: yield syntax is experimental - --> $DIR/feature-gate-coroutines.rs:9:5 + --> $DIR/feature-gate-coroutines.rs:15:5 | LL | yield 0; | ^^^^^^^ @@ -26,12 +35,12 @@ LL | yield 0; = help: add `#![feature(coroutines)]` to the crate attributes to enable error[E0627]: yield expression outside of coroutine literal - --> $DIR/feature-gate-coroutines.rs:2:5 + --> $DIR/feature-gate-coroutines.rs:5:5 | LL | yield true; | ^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 5 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 c3c5aec8824..55243549175 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.rs +++ b/tests/ui/feature-gates/feature-gate-coroutines.rs @@ -1,10 +1,16 @@ +// revisions: e2024 none +//[e2024] compile-flags: --edition 2024 -Zunstable-options + fn main() { - yield true; //~ ERROR yield syntax is experimental + yield true; //[none]~ ERROR yield syntax is experimental //~^ ERROR yield expression outside of coroutine literal + + let _ = || yield true; //[none]~ ERROR yield syntax is experimental } #[cfg(FALSE)] fn foo() { - yield; //~ ERROR yield syntax is experimental - yield 0; //~ ERROR yield syntax is experimental + // Ok in 2024 edition + yield; //[none]~ ERROR yield syntax is experimental + yield 0; //[none]~ ERROR yield syntax is experimental } diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr b/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr new file mode 100644 index 00000000000..1462c41e957 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr @@ -0,0 +1,28 @@ +error[E0658]: gen blocks are experimental + --> $DIR/feature-gate-gen_blocks.rs:5:5 + | +LL | gen {}; + | ^^^^^ + | + = note: see issue #117078 for more information + = help: add `#![feature(gen_blocks)]` to the crate attributes to enable + +error[E0658]: gen blocks are experimental + --> $DIR/feature-gate-gen_blocks.rs:13:5 + | +LL | gen {}; + | ^^^^^ + | + = note: see issue #117078 for more information + = help: add `#![feature(gen_blocks)]` to the crate attributes to enable + +error[E0282]: type annotations needed + --> $DIR/feature-gate-gen_blocks.rs:5:9 + | +LL | gen {}; + | ^^ cannot infer type + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0282, E0658. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr new file mode 100644 index 00000000000..b448c35e846 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr @@ -0,0 +1,9 @@ +error[E0422]: cannot find struct, variant or union type `gen` in this scope + --> $DIR/feature-gate-gen_blocks.rs:5:5 + | +LL | gen {}; + | ^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0422`. diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.rs b/tests/ui/feature-gates/feature-gate-gen_blocks.rs new file mode 100644 index 00000000000..e2e1574a36a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-gen_blocks.rs @@ -0,0 +1,15 @@ +// revisions: e2024 none +//[e2024] compile-flags: --edition 2024 -Zunstable-options + +fn main() { + gen {}; + //[none]~^ ERROR: cannot find struct, variant or union type `gen` + //[e2024]~^^ ERROR: gen blocks are experimental + //[e2024]~| ERROR: type annotations needed +} + +#[cfg(FALSE)] +fn foo() { + gen {}; + //[e2024]~^ ERROR: gen blocks are experimental +}