about summary refs log tree commit diff
path: root/tests/ui/coroutine
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-04-11 13:15:34 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-04-24 08:05:29 +0000
commitaef0f4024aec24fd7e53dbc51883457e44fe17ce (patch)
tree25a26930a8cc3441951ba159f1a632092df41655 /tests/ui/coroutine
parenta589632dad58c2669b7984019efb59917a16ac67 (diff)
downloadrust-aef0f4024aec24fd7e53dbc51883457e44fe17ce.tar.gz
rust-aef0f4024aec24fd7e53dbc51883457e44fe17ce.zip
Error on using `yield` without also using `#[coroutine]` on the closure
And suggest adding the `#[coroutine]` to the closure
Diffstat (limited to 'tests/ui/coroutine')
-rw-r--r--tests/ui/coroutine/addassign-yield.rs8
-rw-r--r--tests/ui/coroutine/auto-trait-regions.rs8
-rw-r--r--tests/ui/coroutine/auxiliary/metadata-sufficient-for-layout.rs1
-rw-r--r--tests/ui/coroutine/auxiliary/unwind-aux.rs5
-rw-r--r--tests/ui/coroutine/auxiliary/xcrate-reachable.rs1
-rw-r--r--tests/ui/coroutine/auxiliary/xcrate.rs12
-rw-r--r--tests/ui/coroutine/borrow-in-tail-expr.rs4
-rw-r--r--tests/ui/coroutine/borrowing.rs6
-rw-r--r--tests/ui/coroutine/borrowing.stderr14
-rw-r--r--tests/ui/coroutine/check-resume-ty-lifetimes-2.rs8
-rw-r--r--tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr12
-rw-r--r--tests/ui/coroutine/check-resume-ty-lifetimes.rs15
-rw-r--r--tests/ui/coroutine/check-resume-ty-lifetimes.stderr6
-rw-r--r--tests/ui/coroutine/clone-impl-static.rs5
-rw-r--r--tests/ui/coroutine/clone-impl-static.stderr16
-rw-r--r--tests/ui/coroutine/clone-impl.rs17
-rw-r--r--tests/ui/coroutine/clone-impl.stderr84
-rw-r--r--tests/ui/coroutine/clone-rpit.next.stderr12
-rw-r--r--tests/ui/coroutine/clone-rpit.rs1
-rw-r--r--tests/ui/coroutine/conditional-drop.rs6
-rw-r--r--tests/ui/coroutine/control-flow.rs12
-rw-r--r--tests/ui/coroutine/coroutine-region-requirements.rs4
-rw-r--r--tests/ui/coroutine/coroutine-resume-after-panic.rs4
-rw-r--r--tests/ui/coroutine/coroutine-with-nll.rs1
-rw-r--r--tests/ui/coroutine/coroutine-with-nll.stderr2
-rw-r--r--tests/ui/coroutine/coroutine-yielding-or-returning-itself.rs6
-rw-r--r--tests/ui/coroutine/coroutine-yielding-or-returning-itself.stderr16
-rw-r--r--tests/ui/coroutine/derived-drop-parent-expr.rs4
-rw-r--r--tests/ui/coroutine/discriminant.rs6
-rw-r--r--tests/ui/coroutine/drop-and-replace.rs5
-rw-r--r--tests/ui/coroutine/drop-control-flow.rs20
-rw-r--r--tests/ui/coroutine/drop-env.rs8
-rw-r--r--tests/ui/coroutine/drop-track-addassign-yield.rs6
-rw-r--r--tests/ui/coroutine/drop-tracking-parent-expression.rs6
-rw-r--r--tests/ui/coroutine/drop-tracking-parent-expression.stderr18
-rw-r--r--tests/ui/coroutine/drop-tracking-yielding-in-match-guards.rs4
-rw-r--r--tests/ui/coroutine/drop-yield-twice.rs4
-rw-r--r--tests/ui/coroutine/drop-yield-twice.stderr4
-rw-r--r--tests/ui/coroutine/dropck-resume.rs5
-rw-r--r--tests/ui/coroutine/dropck-resume.stderr2
-rw-r--r--tests/ui/coroutine/dropck.rs5
-rw-r--r--tests/ui/coroutine/dropck.stderr6
-rw-r--r--tests/ui/coroutine/gen_block.e2024.stderr47
-rw-r--r--tests/ui/coroutine/gen_block.none.stderr66
-rw-r--r--tests/ui/coroutine/gen_block.rs9
-rw-r--r--tests/ui/coroutine/issue-102645.rs5
-rw-r--r--tests/ui/coroutine/issue-102645.stderr2
-rw-r--r--tests/ui/coroutine/issue-105084.rs3
-rw-r--r--tests/ui/coroutine/issue-105084.stderr18
-rw-r--r--tests/ui/coroutine/issue-110929-coroutine-conflict-error-ice.rs5
-rw-r--r--tests/ui/coroutine/issue-113279.rs5
-rw-r--r--tests/ui/coroutine/issue-113279.stderr4
-rw-r--r--tests/ui/coroutine/issue-44197.rs4
-rw-r--r--tests/ui/coroutine/issue-45729-unsafe-in-coroutine.rs5
-rw-r--r--tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr2
-rw-r--r--tests/ui/coroutine/issue-48048.rs2
-rw-r--r--tests/ui/coroutine/issue-52304.rs1
-rw-r--r--tests/ui/coroutine/issue-52398.rs4
-rw-r--r--tests/ui/coroutine/issue-52398.stderr10
-rw-r--r--tests/ui/coroutine/issue-53548.rs4
-rw-r--r--tests/ui/coroutine/issue-57017.rs6
-rw-r--r--tests/ui/coroutine/issue-57084.rs4
-rw-r--r--tests/ui/coroutine/issue-57084.stderr5
-rw-r--r--tests/ui/coroutine/issue-57478.rs15
-rw-r--r--tests/ui/coroutine/issue-58888.rs2
-rw-r--r--tests/ui/coroutine/issue-61442-stmt-expr-with-drop.rs8
-rw-r--r--tests/ui/coroutine/issue-64620-yield-array-element.rs1
-rw-r--r--tests/ui/coroutine/issue-64620-yield-array-element.stderr13
-rw-r--r--tests/ui/coroutine/issue-68112.rs8
-rw-r--r--tests/ui/coroutine/issue-68112.stderr16
-rw-r--r--tests/ui/coroutine/issue-69017.rs1
-rw-r--r--tests/ui/coroutine/issue-69039.rs1
-rw-r--r--tests/ui/coroutine/issue-87142.rs1
-rw-r--r--tests/ui/coroutine/issue-88653.rs1
-rw-r--r--tests/ui/coroutine/issue-91477.rs1
-rw-r--r--tests/ui/coroutine/issue-91477.stderr13
-rw-r--r--tests/ui/coroutine/iterator-count.rs2
-rw-r--r--tests/ui/coroutine/live-upvar-across-yield.rs4
-rw-r--r--tests/ui/coroutine/match-bindings.rs2
-rw-r--r--tests/ui/coroutine/match-bindings.stderr5
-rw-r--r--tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed8
-rw-r--r--tests/ui/coroutine/missing_coroutine_attr_suggestion.rs8
-rw-r--r--tests/ui/coroutine/missing_coroutine_attr_suggestion.stderr13
-rw-r--r--tests/ui/coroutine/nested_coroutine.rs8
-rw-r--r--tests/ui/coroutine/niche-in-coroutine.rs4
-rw-r--r--tests/ui/coroutine/non-static-is-unpin.rs4
-rw-r--r--tests/ui/coroutine/not-send-sync.rs6
-rw-r--r--tests/ui/coroutine/not-send-sync.stderr8
-rw-r--r--tests/ui/coroutine/overlap-locals.rs5
-rw-r--r--tests/ui/coroutine/panic-drops-resume.rs4
-rw-r--r--tests/ui/coroutine/panic-drops.rs17
-rw-r--r--tests/ui/coroutine/panic-safe.rs4
-rw-r--r--tests/ui/coroutine/parent-expression.rs6
-rw-r--r--tests/ui/coroutine/parent-expression.stderr18
-rw-r--r--tests/ui/coroutine/partial-drop.rs45
-rw-r--r--tests/ui/coroutine/partial-initialization-across-yield.rs8
-rw-r--r--tests/ui/coroutine/pattern-borrow.rs2
-rw-r--r--tests/ui/coroutine/pin-box-coroutine.rs6
-rw-r--r--tests/ui/coroutine/polymorphize-args.rs5
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-1.rs8
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-1.stderr12
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-2.rs6
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-2.stderr4
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-3.rs9
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-3.stderr11
-rw-r--r--tests/ui/coroutine/reborrow-mut-upvar.rs2
-rw-r--r--tests/ui/coroutine/reborrow-mut-upvar.stderr5
-rw-r--r--tests/ui/coroutine/ref-escapes-but-not-over-yield.rs9
-rw-r--r--tests/ui/coroutine/ref-escapes-but-not-over-yield.stderr2
-rw-r--r--tests/ui/coroutine/ref-upvar-not-send.rs6
-rw-r--r--tests/ui/coroutine/ref-upvar-not-send.stderr16
-rw-r--r--tests/ui/coroutine/reinit-in-match-guard.rs6
-rw-r--r--tests/ui/coroutine/resume-after-return.rs12
-rw-r--r--tests/ui/coroutine/resume-arg-late-bound.rs4
-rw-r--r--tests/ui/coroutine/resume-arg-late-bound.stderr2
-rw-r--r--tests/ui/coroutine/resume-arg-size.rs8
-rw-r--r--tests/ui/coroutine/resume-live-across-yield.rs5
-rw-r--r--tests/ui/coroutine/retain-resume-ref.rs5
-rw-r--r--tests/ui/coroutine/retain-resume-ref.stderr2
-rw-r--r--tests/ui/coroutine/size-moved-locals.rs4
-rw-r--r--tests/ui/coroutine/sized-yield.rs5
-rw-r--r--tests/ui/coroutine/sized-yield.stderr7
-rw-r--r--tests/ui/coroutine/smoke-resume-args.rs17
-rw-r--r--tests/ui/coroutine/smoke.rs32
-rw-r--r--tests/ui/coroutine/static-coroutine.rs7
-rw-r--r--tests/ui/coroutine/static-mut-reference-across-yield.rs8
-rw-r--r--tests/ui/coroutine/static-not-unpin.current.stderr6
-rw-r--r--tests/ui/coroutine/static-not-unpin.next.stderr6
-rw-r--r--tests/ui/coroutine/static-not-unpin.rs8
-rw-r--r--tests/ui/coroutine/static-reference-across-yield.rs4
-rw-r--r--tests/ui/coroutine/too-live-local-in-immovable-gen.rs2
-rw-r--r--tests/ui/coroutine/too-live-local-in-immovable-gen.stderr5
-rw-r--r--tests/ui/coroutine/too-many-parameters.rs1
-rw-r--r--tests/ui/coroutine/too-many-parameters.stderr2
-rw-r--r--tests/ui/coroutine/type-mismatch-error.rs3
-rw-r--r--tests/ui/coroutine/type-mismatch-error.stderr2
-rw-r--r--tests/ui/coroutine/type-mismatch-signature-deduction.rs1
-rw-r--r--tests/ui/coroutine/type-mismatch-signature-deduction.stderr6
-rw-r--r--tests/ui/coroutine/uninhabited-field.rs4
-rw-r--r--tests/ui/coroutine/unsized-capture-across-yield.rs1
-rw-r--r--tests/ui/coroutine/unsized-capture-across-yield.stderr2
-rw-r--r--tests/ui/coroutine/unsized-local-across-yield.rs1
-rw-r--r--tests/ui/coroutine/unsized-local-across-yield.stderr2
-rw-r--r--tests/ui/coroutine/yield-in-args-rev.rs2
-rw-r--r--tests/ui/coroutine/yield-in-args-rev.stderr5
-rw-r--r--tests/ui/coroutine/yield-in-args.rs1
-rw-r--r--tests/ui/coroutine/yield-in-args.stderr2
-rw-r--r--tests/ui/coroutine/yield-in-const.rs1
-rw-r--r--tests/ui/coroutine/yield-in-const.stderr8
-rw-r--r--tests/ui/coroutine/yield-in-function.rs1
-rw-r--r--tests/ui/coroutine/yield-in-function.stderr13
-rw-r--r--tests/ui/coroutine/yield-in-initializer.rs2
-rw-r--r--tests/ui/coroutine/yield-in-initializer.stderr5
-rw-r--r--tests/ui/coroutine/yield-in-static.rs1
-rw-r--r--tests/ui/coroutine/yield-in-static.stderr8
-rw-r--r--tests/ui/coroutine/yield-outside-coroutine-issue-78653.rs1
-rw-r--r--tests/ui/coroutine/yield-outside-coroutine-issue-78653.stderr13
-rw-r--r--tests/ui/coroutine/yield-subtype.rs2
-rw-r--r--tests/ui/coroutine/yield-subtype.stderr5
-rw-r--r--tests/ui/coroutine/yield-while-iterating.rs14
-rw-r--r--tests/ui/coroutine/yield-while-iterating.stderr4
-rw-r--r--tests/ui/coroutine/yield-while-local-borrowed.rs8
-rw-r--r--tests/ui/coroutine/yield-while-ref-reborrowed.rs21
-rw-r--r--tests/ui/coroutine/yield-while-ref-reborrowed.stderr6
164 files changed, 770 insertions, 496 deletions
diff --git a/tests/ui/coroutine/addassign-yield.rs b/tests/ui/coroutine/addassign-yield.rs
index 8718e73512f..8329b53d715 100644
--- a/tests/ui/coroutine/addassign-yield.rs
+++ b/tests/ui/coroutine/addassign-yield.rs
@@ -5,21 +5,21 @@
 // is being used), we were failing to account for all types that might
 // possibly be live across a yield point.
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn foo() {
-    let _x = static || {
+    let _x = #[coroutine] static || {
         let mut s = String::new();
         s += { yield; "" };
     };
 
-    let _y = static || {
+    let _y = #[coroutine] static || {
         let x = &mut 0;
         *{ yield; x } += match String::new() { _ => 0 };
     };
 
     // Please don't ever actually write something like this
-    let _z = static || {
+    let _z = #[coroutine] static || {
         let x = &mut 0;
         *{
             let inner = &mut 1;
diff --git a/tests/ui/coroutine/auto-trait-regions.rs b/tests/ui/coroutine/auto-trait-regions.rs
index 5fce70e8e54..4c239f9ee76 100644
--- a/tests/ui/coroutine/auto-trait-regions.rs
+++ b/tests/ui/coroutine/auto-trait-regions.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 #![feature(auto_traits)]
 #![feature(negative_impls)]
 
@@ -23,7 +23,7 @@ fn assert_foo<T: Foo>(f: T) {}
 fn main() {
     // Make sure 'static is erased for coroutine interiors so we can't match it in trait selection
     let x: &'static _ = &OnlyFooIfStaticRef(No);
-    let gen = move || {
+    let gen = #[coroutine] move || {
         let x = x;
         yield;
         assert_foo(x);
@@ -33,7 +33,7 @@ fn main() {
 
     // Allow impls which matches any lifetime
     let x = &OnlyFooIfRef(No);
-    let gen = move || {
+    let gen = #[coroutine] move || {
         let x = x;
         yield;
         assert_foo(x);
@@ -41,7 +41,7 @@ fn main() {
     assert_foo(gen); // ok
 
     // Disallow impls which relates lifetimes in the coroutine interior
-    let gen = move || {
+    let gen = #[coroutine] move || {
         let a = A(&mut true, &mut true, No);
         //~^ temporary value dropped while borrowed
         //~| temporary value dropped while borrowed
diff --git a/tests/ui/coroutine/auxiliary/metadata-sufficient-for-layout.rs b/tests/ui/coroutine/auxiliary/metadata-sufficient-for-layout.rs
index 8af6973134a..8ecb8c0c097 100644
--- a/tests/ui/coroutine/auxiliary/metadata-sufficient-for-layout.rs
+++ b/tests/ui/coroutine/auxiliary/metadata-sufficient-for-layout.rs
@@ -5,6 +5,7 @@ use std::marker::Unpin;
 use std::ops::Coroutine;
 
 pub fn g() -> impl Coroutine<(), Yield = (), Return = ()> {
+    #[coroutine]
     || {
         yield;
     }
diff --git a/tests/ui/coroutine/auxiliary/unwind-aux.rs b/tests/ui/coroutine/auxiliary/unwind-aux.rs
index ff1e8ed32cd..5d5e5c2218d 100644
--- a/tests/ui/coroutine/auxiliary/unwind-aux.rs
+++ b/tests/ui/coroutine/auxiliary/unwind-aux.rs
@@ -2,9 +2,10 @@
 //@ no-prefer-dynamic
 //@ edition:2021
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 pub fn run<T>(a: T) {
-    let _ = move || {
+    let _ = #[coroutine]
+    move || {
         drop(a);
         yield;
     };
diff --git a/tests/ui/coroutine/auxiliary/xcrate-reachable.rs b/tests/ui/coroutine/auxiliary/xcrate-reachable.rs
index 673153f0619..0b5d1882300 100644
--- a/tests/ui/coroutine/auxiliary/xcrate-reachable.rs
+++ b/tests/ui/coroutine/auxiliary/xcrate-reachable.rs
@@ -7,6 +7,7 @@ fn msg() -> u32 {
 }
 
 pub fn foo() -> impl Coroutine<(), Yield = (), Return = u32> {
+    #[coroutine]
     || {
         yield;
         return msg();
diff --git a/tests/ui/coroutine/auxiliary/xcrate.rs b/tests/ui/coroutine/auxiliary/xcrate.rs
index f749a95ad35..52f188135bd 100644
--- a/tests/ui/coroutine/auxiliary/xcrate.rs
+++ b/tests/ui/coroutine/auxiliary/xcrate.rs
@@ -1,9 +1,10 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::marker::Unpin;
 use std::ops::Coroutine;
 
 pub fn foo() -> impl Coroutine<(), Yield = (), Return = ()> {
+    #[coroutine]
     || {
         if false {
             yield;
@@ -12,7 +13,10 @@ pub fn foo() -> impl Coroutine<(), Yield = (), Return = ()> {
 }
 
 pub fn bar<T: 'static>(t: T) -> Box<Coroutine<(), Yield = T, Return = ()> + Unpin> {
-    Box::new(|| {
-        yield t;
-    })
+    Box::new(
+        #[coroutine]
+        || {
+            yield t;
+        },
+    )
 }
diff --git a/tests/ui/coroutine/borrow-in-tail-expr.rs b/tests/ui/coroutine/borrow-in-tail-expr.rs
index 2f0aa62019e..380e95cfc77 100644
--- a/tests/ui/coroutine/borrow-in-tail-expr.rs
+++ b/tests/ui/coroutine/borrow-in-tail-expr.rs
@@ -1,9 +1,9 @@
 //@ run-pass
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn main() {
-    let _a = || {
+    let _a = #[coroutine] || {
         yield;
         let a = String::new();
         a.len()
diff --git a/tests/ui/coroutine/borrowing.rs b/tests/ui/coroutine/borrowing.rs
index 778eed8bd0d..a6628766c1b 100644
--- a/tests/ui/coroutine/borrowing.rs
+++ b/tests/ui/coroutine/borrowing.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
@@ -6,13 +6,13 @@ use std::pin::Pin;
 fn main() {
     let _b = {
         let a = 3;
-        Pin::new(&mut || yield &a).resume(())
+        Pin::new(&mut #[coroutine] || yield &a).resume(())
         //~^ ERROR: `a` does not live long enough
     };
 
     let _b = {
         let a = 3;
-        || {
+        #[coroutine] || {
             yield &a
             //~^ ERROR: `a` does not live long enough
         }
diff --git a/tests/ui/coroutine/borrowing.stderr b/tests/ui/coroutine/borrowing.stderr
index acd4cdafdfd..9132e5d84ed 100644
--- a/tests/ui/coroutine/borrowing.stderr
+++ b/tests/ui/coroutine/borrowing.stderr
@@ -1,13 +1,13 @@
 error[E0597]: `a` does not live long enough
-  --> $DIR/borrowing.rs:9:33
+  --> $DIR/borrowing.rs:9:46
    |
 LL |     let _b = {
    |         -- borrow later stored here
 LL |         let a = 3;
-LL |         Pin::new(&mut || yield &a).resume(())
-   |                       --        ^ borrowed value does not live long enough
-   |                       |
-   |                       value captured here by coroutine
+LL |         Pin::new(&mut #[coroutine] || yield &a).resume(())
+   |                                    --        ^ borrowed value does not live long enough
+   |                                    |
+   |                                    value captured here by coroutine
 LL |
 LL |     };
    |     - `a` dropped here while still borrowed
@@ -18,8 +18,8 @@ error[E0597]: `a` does not live long enough
 LL |     let _b = {
    |         -- borrow later stored here
 LL |         let a = 3;
-LL |         || {
-   |         -- value captured here by coroutine
+LL |         #[coroutine] || {
+   |                      -- value captured here by coroutine
 LL |             yield &a
    |                    ^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs b/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs
index a316c50e867..327756ebe66 100644
--- a/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs
+++ b/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs
@@ -7,27 +7,27 @@ struct Contravariant<'a>(fn(&'a ()));
 struct Covariant<'a>(fn() -> &'a ());
 
 fn bad1<'short, 'long: 'short>() -> impl Coroutine<Covariant<'short>> {
-    |_: Covariant<'short>| {
+    #[coroutine] |_: Covariant<'short>| {
         let a: Covariant<'long> = yield ();
         //~^ ERROR lifetime may not live long enough
     }
 }
 
 fn bad2<'short, 'long: 'short>() -> impl Coroutine<Contravariant<'long>> {
-    |_: Contravariant<'long>| {
+    #[coroutine] |_: Contravariant<'long>| {
         let a: Contravariant<'short> = yield ();
         //~^ ERROR lifetime may not live long enough
     }
 }
 
 fn good1<'short, 'long: 'short>() -> impl Coroutine<Covariant<'long>> {
-    |_: Covariant<'long>| {
+    #[coroutine] |_: Covariant<'long>| {
         let a: Covariant<'short> = yield ();
     }
 }
 
 fn good2<'short, 'long: 'short>() -> impl Coroutine<Contravariant<'short>> {
-    |_: Contravariant<'short>| {
+    #[coroutine] |_: Contravariant<'short>| {
         let a: Contravariant<'long> = yield ();
     }
 }
diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr b/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr
index e0cbca2dd52..8eb7ab3501b 100644
--- a/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr
+++ b/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr
@@ -5,15 +5,15 @@ LL | fn bad1<'short, 'long: 'short>() -> impl Coroutine<Covariant<'short>> {
    |         ------  ----- lifetime `'long` defined here
    |         |
    |         lifetime `'short` defined here
-LL |     |_: Covariant<'short>| {
+LL |     #[coroutine] |_: Covariant<'short>| {
 LL |         let a: Covariant<'long> = yield ();
    |                ^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
    |
    = help: consider adding the following bound: `'short: 'long`
 help: consider adding 'move' keyword before the nested closure
    |
-LL |     move |_: Covariant<'short>| {
-   |     ++++
+LL |     #[coroutine] move |_: Covariant<'short>| {
+   |                  ++++
 
 error: lifetime may not live long enough
   --> $DIR/check-resume-ty-lifetimes-2.rs:18:40
@@ -22,15 +22,15 @@ LL | fn bad2<'short, 'long: 'short>() -> impl Coroutine<Contravariant<'long>> {
    |         ------  ----- lifetime `'long` defined here
    |         |
    |         lifetime `'short` defined here
-LL |     |_: Contravariant<'long>| {
+LL |     #[coroutine] |_: Contravariant<'long>| {
 LL |         let a: Contravariant<'short> = yield ();
    |                                        ^^^^^^^^ yielding this value requires that `'short` must outlive `'long`
    |
    = help: consider adding the following bound: `'short: 'long`
 help: consider adding 'move' keyword before the nested closure
    |
-LL |     move |_: Contravariant<'long>| {
-   |     ++++
+LL |     #[coroutine] move |_: Contravariant<'long>| {
+   |                  ++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes.rs b/tests/ui/coroutine/check-resume-ty-lifetimes.rs
index add0b5080a8..b75e46c541c 100644
--- a/tests/ui/coroutine/check-resume-ty-lifetimes.rs
+++ b/tests/ui/coroutine/check-resume-ty-lifetimes.rs
@@ -1,5 +1,5 @@
 #![feature(coroutine_trait)]
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 #![allow(unused)]
 
 use std::ops::Coroutine;
@@ -9,11 +9,14 @@ use std::pin::pin;
 fn mk_static(s: &str) -> &'static str {
     let mut storage: Option<&'static str> = None;
 
-    let mut coroutine = pin!(|_: &str| {
-        let x: &'static str = yield ();
-        //~^ ERROR lifetime may not live long enough
-        storage = Some(x);
-    });
+    let mut coroutine = pin!(
+        #[coroutine]
+        |_: &str| {
+            let x: &'static str = yield ();
+            //~^ ERROR lifetime may not live long enough
+            storage = Some(x);
+        }
+    );
 
     coroutine.as_mut().resume(s);
     coroutine.as_mut().resume(s);
diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes.stderr b/tests/ui/coroutine/check-resume-ty-lifetimes.stderr
index f373aa778a8..1fbaeb9f7fa 100644
--- a/tests/ui/coroutine/check-resume-ty-lifetimes.stderr
+++ b/tests/ui/coroutine/check-resume-ty-lifetimes.stderr
@@ -1,11 +1,11 @@
 error: lifetime may not live long enough
-  --> $DIR/check-resume-ty-lifetimes.rs:13:16
+  --> $DIR/check-resume-ty-lifetimes.rs:15:20
    |
 LL | fn mk_static(s: &str) -> &'static str {
    |                 - let's call the lifetime of this reference `'1`
 ...
-LL |         let x: &'static str = yield ();
-   |                ^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
+LL |             let x: &'static str = yield ();
+   |                    ^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coroutine/clone-impl-static.rs b/tests/ui/coroutine/clone-impl-static.rs
index 9a165cf4672..56d1ccac703 100644
--- a/tests/ui/coroutine/clone-impl-static.rs
+++ b/tests/ui/coroutine/clone-impl-static.rs
@@ -1,10 +1,11 @@
 // gate-test-coroutine_clone
 // Verifies that static coroutines cannot be cloned/copied.
 
-#![feature(coroutines, coroutine_clone)]
+#![feature(coroutines, coroutine_clone, stmt_expr_attributes)]
 
 fn main() {
-    let gen = static move || {
+    let gen = #[coroutine]
+    static move || {
         yield;
     };
     check_copy(&gen);
diff --git a/tests/ui/coroutine/clone-impl-static.stderr b/tests/ui/coroutine/clone-impl-static.stderr
index 8fa9fb12bf6..43920326d5d 100644
--- a/tests/ui/coroutine/clone-impl-static.stderr
+++ b/tests/ui/coroutine/clone-impl-static.stderr
@@ -1,27 +1,27 @@
-error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:7:15: 7:29}: Copy` is not satisfied
-  --> $DIR/clone-impl-static.rs:10:16
+error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:8:5: 8:19}: Copy` is not satisfied
+  --> $DIR/clone-impl-static.rs:11:16
    |
 LL |     check_copy(&gen);
-   |     ---------- ^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:7:15: 7:29}`
+   |     ---------- ^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:8:5: 8:19}`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl-static.rs:16:18
+  --> $DIR/clone-impl-static.rs:17:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:7:15: 7:29}: Clone` is not satisfied
-  --> $DIR/clone-impl-static.rs:12:17
+error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:8:5: 8:19}: Clone` is not satisfied
+  --> $DIR/clone-impl-static.rs:13:17
    |
 LL |     check_clone(&gen);
-   |     ----------- ^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:7:15: 7:29}`
+   |     ----------- ^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:8:5: 8:19}`
    |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl-static.rs:17:19
+  --> $DIR/clone-impl-static.rs:18:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`
diff --git a/tests/ui/coroutine/clone-impl.rs b/tests/ui/coroutine/clone-impl.rs
index fffdae632ef..94420e56a22 100644
--- a/tests/ui/coroutine/clone-impl.rs
+++ b/tests/ui/coroutine/clone-impl.rs
@@ -2,13 +2,14 @@
 // Verifies that non-static coroutines can be cloned/copied if all their upvars and locals held
 // across awaits can be cloned/copied.
 
-#![feature(coroutines, coroutine_clone)]
+#![feature(coroutines, coroutine_clone, stmt_expr_attributes)]
 
 struct NonClone;
 
 fn test1() {
     let copyable: u32 = 123;
-    let gen_copy_0 = move || {
+    let gen_copy_0 = #[coroutine]
+    move || {
         yield;
         drop(copyable);
     };
@@ -18,7 +19,8 @@ fn test1() {
 
 fn test2() {
     let copyable: u32 = 123;
-    let gen_copy_1 = move || {
+    let gen_copy_1 = #[coroutine]
+    move || {
         /*
         let v = vec!['a'];
         let n = NonClone;
@@ -37,7 +39,8 @@ fn test2() {
 
 fn test3() {
     let clonable_0: Vec<u32> = Vec::new();
-    let gen_clone_0 = move || {
+    let gen_clone_0 = #[coroutine]
+    move || {
         let v = vec!['a'];
         yield;
         drop(v);
@@ -51,7 +54,8 @@ fn test3() {
 
 fn test4() {
     let clonable_1: Vec<u32> = Vec::new();
-    let gen_clone_1 = move || {
+    let gen_clone_1 = #[coroutine]
+    move || {
         let v = vec!['a'];
         /*
         let n = NonClone;
@@ -71,7 +75,8 @@ fn test4() {
 
 fn test5() {
     let non_clonable: NonClone = NonClone;
-    let gen_non_clone = move || {
+    let gen_non_clone = #[coroutine]
+    move || {
         yield;
         drop(non_clonable);
     };
diff --git a/tests/ui/coroutine/clone-impl.stderr b/tests/ui/coroutine/clone-impl.stderr
index b454846faac..5330d3bbd39 100644
--- a/tests/ui/coroutine/clone-impl.stderr
+++ b/tests/ui/coroutine/clone-impl.stderr
@@ -1,76 +1,76 @@
-error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`
-  --> $DIR/clone-impl.rs:46:5
+error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`
+  --> $DIR/clone-impl.rs:49:5
    |
-LL |     let gen_clone_0 = move || {
-   |                       ------- within this `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`
+LL |     move || {
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`
 ...
 LL |     check_copy(&gen_clone_0);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`, the trait `Copy` is not implemented for `Vec<u32>`, which is required by `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}: Copy`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`, the trait `Copy` is not implemented for `Vec<u32>`, which is required by `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}: Copy`
    |
 note: captured value does not implement `Copy`
-  --> $DIR/clone-impl.rs:44:14
+  --> $DIR/clone-impl.rs:47:14
    |
 LL |         drop(clonable_0);
    |              ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl.rs:84:18
+  --> $DIR/clone-impl.rs:89:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`
-  --> $DIR/clone-impl.rs:46:5
+error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`
+  --> $DIR/clone-impl.rs:49:5
    |
-LL |     let gen_clone_0 = move || {
-   |                       ------- within this `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`
+LL |     move || {
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`
 ...
 LL |     check_copy(&gen_clone_0);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`, the trait `Copy` is not implemented for `Vec<char>`, which is required by `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}: Copy`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`, the trait `Copy` is not implemented for `Vec<char>`, which is required by `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}: Copy`
    |
 note: coroutine does not implement `Copy` as this value is used across a yield
-  --> $DIR/clone-impl.rs:42:9
+  --> $DIR/clone-impl.rs:45:9
    |
 LL |         let v = vec!['a'];
    |             - has type `Vec<char>` which does not implement `Copy`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `v` maybe used later
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl.rs:84:18
+  --> $DIR/clone-impl.rs:89:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`
-  --> $DIR/clone-impl.rs:66:5
+error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`
+  --> $DIR/clone-impl.rs:70:5
    |
-LL |     let gen_clone_1 = move || {
-   |                       ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`
+LL |     move || {
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`
 ...
 LL |     check_copy(&gen_clone_1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`, the trait `Copy` is not implemented for `Vec<u32>`, which is required by `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}: Copy`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`, the trait `Copy` is not implemented for `Vec<u32>`, which is required by `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}: Copy`
    |
 note: captured value does not implement `Copy`
-  --> $DIR/clone-impl.rs:64:14
+  --> $DIR/clone-impl.rs:68:14
    |
 LL |         drop(clonable_1);
    |              ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl.rs:84:18
+  --> $DIR/clone-impl.rs:89:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`
-  --> $DIR/clone-impl.rs:66:5
+error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`
+  --> $DIR/clone-impl.rs:70:5
    |
-LL |     let gen_clone_1 = move || {
-   |                       ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`
+LL |     move || {
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`
 ...
 LL |     check_copy(&gen_clone_1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`, the trait `Copy` is not implemented for `Vec<char>`, which is required by `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}: Copy`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`, the trait `Copy` is not implemented for `Vec<char>`, which is required by `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}: Copy`
    |
 note: coroutine does not implement `Copy` as this value is used across a yield
-  --> $DIR/clone-impl.rs:60:9
+  --> $DIR/clone-impl.rs:64:9
    |
 LL |         let v = vec!['a'];
    |             - has type `Vec<char>` which does not implement `Copy`
@@ -78,27 +78,27 @@ LL |         let v = vec!['a'];
 LL |         yield;
    |         ^^^^^ yield occurs here, with `v` maybe used later
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl.rs:84:18
+  --> $DIR/clone-impl.rs:89:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
-error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`
-  --> $DIR/clone-impl.rs:78:5
+error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`
+  --> $DIR/clone-impl.rs:83:5
    |
-LL |     let gen_non_clone = move || {
-   |                         ------- within this `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`
+LL |     move || {
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`
 ...
 LL |     check_copy(&gen_non_clone);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`, the trait `Copy` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}: Copy`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`, the trait `Copy` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}: Copy`
    |
 note: captured value does not implement `Copy`
-  --> $DIR/clone-impl.rs:76:14
+  --> $DIR/clone-impl.rs:81:14
    |
 LL |         drop(non_clonable);
    |              ^^^^^^^^^^^^ has type `NonClone` which does not implement `Copy`
 note: required by a bound in `check_copy`
-  --> $DIR/clone-impl.rs:84:18
+  --> $DIR/clone-impl.rs:89:18
    |
 LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
@@ -108,22 +108,22 @@ LL + #[derive(Copy)]
 LL | struct NonClone;
    |
 
-error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`
-  --> $DIR/clone-impl.rs:80:5
+error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`
+  --> $DIR/clone-impl.rs:85:5
    |
-LL |     let gen_non_clone = move || {
-   |                         ------- within this `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`
+LL |     move || {
+   |     ------- within this `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`
 ...
 LL |     check_clone(&gen_non_clone);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`, the trait `Clone` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}: Clone`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`, the trait `Clone` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}: Clone`
    |
 note: captured value does not implement `Clone`
-  --> $DIR/clone-impl.rs:76:14
+  --> $DIR/clone-impl.rs:81:14
    |
 LL |         drop(non_clonable);
    |              ^^^^^^^^^^^^ has type `NonClone` which does not implement `Clone`
 note: required by a bound in `check_clone`
-  --> $DIR/clone-impl.rs:85:19
+  --> $DIR/clone-impl.rs:90:19
    |
 LL | fn check_clone<T: Clone>(_x: &T) {}
    |                   ^^^^^ required by this bound in `check_clone`
diff --git a/tests/ui/coroutine/clone-rpit.next.stderr b/tests/ui/coroutine/clone-rpit.next.stderr
index 41aa2d63af0..c223f1f211a 100644
--- a/tests/ui/coroutine/clone-rpit.next.stderr
+++ b/tests/ui/coroutine/clone-rpit.next.stderr
@@ -5,32 +5,32 @@ LL | pub fn foo<'a, 'b>() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: ...which requires coroutine witness types for `foo::{closure#0}`...
-  --> $DIR/clone-rpit.rs:14:5
+  --> $DIR/clone-rpit.rs:15:5
    |
 LL |     move |_: ()| {
    |     ^^^^^^^^^^^^
 note: ...which requires promoting constants in MIR for `foo::{closure#0}`...
-  --> $DIR/clone-rpit.rs:14:5
+  --> $DIR/clone-rpit.rs:15:5
    |
 LL |     move |_: ()| {
    |     ^^^^^^^^^^^^
 note: ...which requires checking if `foo::{closure#0}` contains FFI-unwind calls...
-  --> $DIR/clone-rpit.rs:14:5
+  --> $DIR/clone-rpit.rs:15:5
    |
 LL |     move |_: ()| {
    |     ^^^^^^^^^^^^
 note: ...which requires building MIR for `foo::{closure#0}`...
-  --> $DIR/clone-rpit.rs:14:5
+  --> $DIR/clone-rpit.rs:15:5
    |
 LL |     move |_: ()| {
    |     ^^^^^^^^^^^^
 note: ...which requires match-checking `foo::{closure#0}`...
-  --> $DIR/clone-rpit.rs:14:5
+  --> $DIR/clone-rpit.rs:15:5
    |
 LL |     move |_: ()| {
    |     ^^^^^^^^^^^^
 note: ...which requires type-checking `foo::{closure#0}`...
-  --> $DIR/clone-rpit.rs:14:5
+  --> $DIR/clone-rpit.rs:15:5
    |
 LL |     move |_: ()| {
    |     ^^^^^^^^^^^^
diff --git a/tests/ui/coroutine/clone-rpit.rs b/tests/ui/coroutine/clone-rpit.rs
index 0df9bf61601..66569b4f427 100644
--- a/tests/ui/coroutine/clone-rpit.rs
+++ b/tests/ui/coroutine/clone-rpit.rs
@@ -11,6 +11,7 @@
 // witness types, which we don't know until after borrowck. When we later check
 // the goal for correctness, we want to be able to bind the `impl Clone` opaque.
 pub fn foo<'a, 'b>() -> impl Clone {
+    #[coroutine]
     move |_: ()| {
         let () = yield ();
     }
diff --git a/tests/ui/coroutine/conditional-drop.rs b/tests/ui/coroutine/conditional-drop.rs
index 65d3a9e701e..52e1b561946 100644
--- a/tests/ui/coroutine/conditional-drop.rs
+++ b/tests/ui/coroutine/conditional-drop.rs
@@ -3,7 +3,7 @@
 //@ revisions: default nomiropt
 //@[nomiropt]compile-flags: -Z mir-opt-level=0
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
@@ -29,7 +29,7 @@ fn main() {
 }
 
 fn t1() {
-    let mut a = || {
+    let mut a = #[coroutine] || {
         let b = B;
         if test() {
             drop(b);
@@ -45,7 +45,7 @@ fn t1() {
 }
 
 fn t2() {
-    let mut a = || {
+    let mut a = #[coroutine] || {
         let b = B;
         if test2() {
             drop(b);
diff --git a/tests/ui/coroutine/control-flow.rs b/tests/ui/coroutine/control-flow.rs
index 9070ba17856..f64b6f73883 100644
--- a/tests/ui/coroutine/control-flow.rs
+++ b/tests/ui/coroutine/control-flow.rs
@@ -3,7 +3,7 @@
 //@ revisions: default nomiropt
 //@[nomiropt]compile-flags: -Z mir-opt-level=0
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::{CoroutineState, Coroutine};
 use std::pin::Pin;
@@ -24,25 +24,25 @@ fn finish<T>(mut amt: usize, mut t: T) -> T::Return
 }
 
 fn main() {
-    finish(1, || yield);
-    finish(8, || {
+    finish(1, #[coroutine] || yield);
+    finish(8, #[coroutine] || {
         for _ in 0..8 {
             yield;
         }
     });
-    finish(1, || {
+    finish(1, #[coroutine] || {
         if true {
             yield;
         } else {
         }
     });
-    finish(1, || {
+    finish(1, #[coroutine] || {
         if false {
         } else {
             yield;
         }
     });
-    finish(2, || {
+    finish(2, #[coroutine] || {
         if { yield; false } {
             yield;
             panic!()
diff --git a/tests/ui/coroutine/coroutine-region-requirements.rs b/tests/ui/coroutine/coroutine-region-requirements.rs
index 8bc34fdd2f0..ab6f16995e2 100644
--- a/tests/ui/coroutine/coroutine-region-requirements.rs
+++ b/tests/ui/coroutine/coroutine-region-requirements.rs
@@ -1,9 +1,9 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 use std::ops::{Coroutine, CoroutineState};
 use std::pin::Pin;
 
 fn dangle(x: &mut i32) -> &'static mut i32 {
-    let mut g = || {
+    let mut g = #[coroutine] || {
         yield;
         x
     };
diff --git a/tests/ui/coroutine/coroutine-resume-after-panic.rs b/tests/ui/coroutine/coroutine-resume-after-panic.rs
index 8445bf7e635..2745ebc6132 100644
--- a/tests/ui/coroutine/coroutine-resume-after-panic.rs
+++ b/tests/ui/coroutine/coroutine-resume-after-panic.rs
@@ -5,7 +5,7 @@
 
 // Test that we get the correct message for resuming a panicked coroutine.
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::{
     ops::Coroutine,
@@ -14,7 +14,7 @@ use std::{
 };
 
 fn main() {
-    let mut g = || {
+    let mut g = #[coroutine] || {
         panic!();
         yield;
     };
diff --git a/tests/ui/coroutine/coroutine-with-nll.rs b/tests/ui/coroutine/coroutine-with-nll.rs
index 28a3643fbc9..fa77ab4e049 100644
--- a/tests/ui/coroutine/coroutine-with-nll.rs
+++ b/tests/ui/coroutine/coroutine-with-nll.rs
@@ -1,6 +1,7 @@
 #![feature(coroutines)]
 
 fn main() {
+    #[coroutine]
     || {
         // The reference in `_a` is a Legal with NLL since it ends before the yield
         let _a = &mut true;
diff --git a/tests/ui/coroutine/coroutine-with-nll.stderr b/tests/ui/coroutine/coroutine-with-nll.stderr
index 77e8bb1f92e..3f3d51da311 100644
--- a/tests/ui/coroutine/coroutine-with-nll.stderr
+++ b/tests/ui/coroutine/coroutine-with-nll.stderr
@@ -1,5 +1,5 @@
 error[E0626]: borrow may still be in use when coroutine yields
-  --> $DIR/coroutine-with-nll.rs:7:17
+  --> $DIR/coroutine-with-nll.rs:8:17
    |
 LL |         let b = &mut true;
    |                 ^^^^^^^^^
diff --git a/tests/ui/coroutine/coroutine-yielding-or-returning-itself.rs b/tests/ui/coroutine/coroutine-yielding-or-returning-itself.rs
index 3c91b3c9329..f3110d71d0d 100644
--- a/tests/ui/coroutine/coroutine-yielding-or-returning-itself.rs
+++ b/tests/ui/coroutine/coroutine-yielding-or-returning-itself.rs
@@ -1,5 +1,5 @@
 #![feature(coroutine_trait)]
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 // Test that we cannot create a coroutine that returns a value of its
 // own type.
@@ -12,7 +12,7 @@ pub fn want_cyclic_coroutine_return<T>(_: T)
 }
 
 fn supply_cyclic_coroutine_return() {
-    want_cyclic_coroutine_return(|| {
+    want_cyclic_coroutine_return(#[coroutine] || {
         //~^ ERROR type mismatch
         if false { yield None.unwrap(); }
         None.unwrap()
@@ -25,7 +25,7 @@ pub fn want_cyclic_coroutine_yield<T>(_: T)
 }
 
 fn supply_cyclic_coroutine_yield() {
-    want_cyclic_coroutine_yield(|| {
+    want_cyclic_coroutine_yield(#[coroutine] || {
         //~^ ERROR type mismatch
         if false { yield None.unwrap(); }
         None.unwrap()
diff --git a/tests/ui/coroutine/coroutine-yielding-or-returning-itself.stderr b/tests/ui/coroutine/coroutine-yielding-or-returning-itself.stderr
index 325030524ba..32799148ae1 100644
--- a/tests/ui/coroutine/coroutine-yielding-or-returning-itself.stderr
+++ b/tests/ui/coroutine/coroutine-yielding-or-returning-itself.stderr
@@ -1,8 +1,8 @@
-error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:15:34: 15:36} as Coroutine>::Return == {coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:15:34: 15:36}`
-  --> $DIR/coroutine-yielding-or-returning-itself.rs:15:34
+error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:15:47: 15:49} as Coroutine>::Return == {coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:15:47: 15:49}`
+  --> $DIR/coroutine-yielding-or-returning-itself.rs:15:47
    |
-LL |       want_cyclic_coroutine_return(|| {
-   |  _____----------------------------_^
+LL |       want_cyclic_coroutine_return(#[coroutine] || {
+   |  _____----------------------------______________^
    | |     |
    | |     required by a bound introduced by this call
 LL | |
@@ -23,11 +23,11 @@ LL | pub fn want_cyclic_coroutine_return<T>(_: T)
 LL |     where T: Coroutine<Yield = (), Return = T>
    |                                    ^^^^^^^^^^ required by this bound in `want_cyclic_coroutine_return`
 
-error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:28:33: 28:35} as Coroutine>::Yield == {coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:28:33: 28:35}`
-  --> $DIR/coroutine-yielding-or-returning-itself.rs:28:33
+error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:28:46: 28:48} as Coroutine>::Yield == {coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:28:46: 28:48}`
+  --> $DIR/coroutine-yielding-or-returning-itself.rs:28:46
    |
-LL |       want_cyclic_coroutine_yield(|| {
-   |  _____---------------------------_^
+LL |       want_cyclic_coroutine_yield(#[coroutine] || {
+   |  _____---------------------------______________^
    | |     |
    | |     required by a bound introduced by this call
 LL | |
diff --git a/tests/ui/coroutine/derived-drop-parent-expr.rs b/tests/ui/coroutine/derived-drop-parent-expr.rs
index 71f7506ab84..cc217e4960e 100644
--- a/tests/ui/coroutine/derived-drop-parent-expr.rs
+++ b/tests/ui/coroutine/derived-drop-parent-expr.rs
@@ -1,7 +1,7 @@
 //@ build-pass
 
 //! Like drop-tracking-parent-expression, but also tests that this doesn't ICE when building MIR
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn assert_send<T: Send>(_thing: T) {}
 
@@ -9,7 +9,7 @@ fn assert_send<T: Send>(_thing: T) {}
 pub struct Client { pub nickname: String }
 
 fn main() {
-    let g = move || match drop(Client { ..Client::default() }) {
+    let g = #[coroutine] move || match drop(Client { ..Client::default() }) {
             _status => yield,
         };
     assert_send(g);
diff --git a/tests/ui/coroutine/discriminant.rs b/tests/ui/coroutine/discriminant.rs
index a44d8f74746..d6879e21825 100644
--- a/tests/ui/coroutine/discriminant.rs
+++ b/tests/ui/coroutine/discriminant.rs
@@ -86,7 +86,7 @@ fn cycle(
 fn main() {
     // Has only one invalid discr. value.
     let gen_u8_tiny_niche = || {
-        || {
+        #[coroutine] || {
             // 3 reserved variants
 
             yield250!(); // 253 variants
@@ -98,7 +98,7 @@ fn main() {
 
     // Uses all values in the u8 discriminant.
     let gen_u8_full = || {
-        || {
+        #[coroutine] || {
             // 3 reserved variants
 
             yield250!(); // 253 variants
@@ -111,7 +111,7 @@ fn main() {
 
     // Barely needs a u16 discriminant.
     let gen_u16 = || {
-        || {
+        #[coroutine] || {
             // 3 reserved variants
 
             yield250!(); // 253 variants
diff --git a/tests/ui/coroutine/drop-and-replace.rs b/tests/ui/coroutine/drop-and-replace.rs
index 6e30d76512b..d3d7e000020 100644
--- a/tests/ui/coroutine/drop-and-replace.rs
+++ b/tests/ui/coroutine/drop-and-replace.rs
@@ -4,7 +4,7 @@
 // #60187, this produced incorrect code for coroutines when a saved local was
 // re-assigned.
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::{Coroutine, CoroutineState};
 use std::pin::Pin;
@@ -17,7 +17,8 @@ impl Drop for Foo {
 }
 
 fn main() {
-    let mut a = || {
+    let mut a = #[coroutine]
+    || {
         let mut x = Foo(4);
         yield;
         assert_eq!(x.0, 4);
diff --git a/tests/ui/coroutine/drop-control-flow.rs b/tests/ui/coroutine/drop-control-flow.rs
index f4e8eed4f8d..f576b1b7594 100644
--- a/tests/ui/coroutine/drop-control-flow.rs
+++ b/tests/ui/coroutine/drop-control-flow.rs
@@ -4,7 +4,7 @@
 // and also that values that are dropped along all paths to a yield do not get
 // included in the coroutine type.
 
-#![feature(coroutines, negative_impls)]
+#![feature(coroutines, negative_impls, stmt_expr_attributes)]
 #![allow(unused_assignments, dead_code)]
 
 struct Ptr;
@@ -19,7 +19,7 @@ fn assert_send<T: Send>(_: T) {}
 
 // This test case is reduced from tests/ui/drop/dynamic-drop-async.rs
 fn one_armed_if(arg: bool) {
-    let _ = || {
+    let _ = #[coroutine] || {
         let arr = [Ptr];
         if arg {
             drop(arr);
@@ -29,7 +29,7 @@ fn one_armed_if(arg: bool) {
 }
 
 fn two_armed_if(arg: bool) {
-    assert_send(|| {
+    assert_send(#[coroutine] || {
         let arr = [Ptr];
         if arg {
             drop(arr);
@@ -41,7 +41,7 @@ fn two_armed_if(arg: bool) {
 }
 
 fn if_let(arg: Option<i32>) {
-    let _ = || {
+    let _ = #[coroutine] || {
         let arr = [Ptr];
         if let Some(_) = arg {
             drop(arr);
@@ -51,7 +51,7 @@ fn if_let(arg: Option<i32>) {
 }
 
 fn init_in_if(arg: bool) {
-    assert_send(|| {
+    assert_send(#[coroutine] || {
         let mut x = NonSend;
         drop(x);
         if arg {
@@ -63,7 +63,7 @@ fn init_in_if(arg: bool) {
 }
 
 fn init_in_match_arm(arg: Option<i32>) {
-    assert_send(|| {
+    assert_send(#[coroutine] || {
         let mut x = NonSend;
         drop(x);
         match arg {
@@ -74,7 +74,7 @@ fn init_in_match_arm(arg: Option<i32>) {
 }
 
 fn reinit() {
-    let _ = || {
+    let _ = #[coroutine] || {
         let mut arr = [Ptr];
         drop(arr);
         arr = [Ptr];
@@ -83,7 +83,7 @@ fn reinit() {
 }
 
 fn loop_uninit() {
-    let _ = || {
+    let _ = #[coroutine] || {
         let mut arr = [Ptr];
         let mut count = 0;
         drop(arr);
@@ -96,7 +96,7 @@ fn loop_uninit() {
 }
 
 fn nested_loop() {
-    let _ = || {
+    let _ = #[coroutine] || {
         let mut arr = [Ptr];
         let mut count = 0;
         drop(arr);
@@ -111,7 +111,7 @@ fn nested_loop() {
 }
 
 fn loop_continue(b: bool) {
-    let _ = || {
+    let _ = #[coroutine] || {
         let mut arr = [Ptr];
         let mut count = 0;
         drop(arr);
diff --git a/tests/ui/coroutine/drop-env.rs b/tests/ui/coroutine/drop-env.rs
index b189ab81499..d36228dc849 100644
--- a/tests/ui/coroutine/drop-env.rs
+++ b/tests/ui/coroutine/drop-env.rs
@@ -3,7 +3,7 @@
 //@ revisions: default nomiropt
 //@[nomiropt]compile-flags: -Z mir-opt-level=0
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 #![allow(dropping_copy_types)]
 
 use std::ops::Coroutine;
@@ -28,7 +28,7 @@ fn main() {
 
 fn t1() {
     let b = B;
-    let mut foo = || {
+    let mut foo = #[coroutine] || {
         yield;
         drop(b);
     };
@@ -42,7 +42,7 @@ fn t1() {
 
 fn t2() {
     let b = B;
-    let mut foo = || {
+    let mut foo = #[coroutine] || {
         yield b;
     };
 
@@ -55,7 +55,7 @@ fn t2() {
 
 fn t3() {
     let b = B;
-    let foo = || {
+    let foo = #[coroutine] || {
         yield;
         drop(b);
     };
diff --git a/tests/ui/coroutine/drop-track-addassign-yield.rs b/tests/ui/coroutine/drop-track-addassign-yield.rs
index b1a4bd79f31..537e66c41b2 100644
--- a/tests/ui/coroutine/drop-track-addassign-yield.rs
+++ b/tests/ui/coroutine/drop-track-addassign-yield.rs
@@ -3,10 +3,10 @@
 // Based on addassign-yield.rs, but with drop tracking enabled. Originally we did not implement
 // the fake_read callback on ExprUseVisitor which caused this case to break.
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn foo() {
-    let _y = static || {
+    let _y = #[coroutine] static || {
         let x = &mut 0;
         *{
             yield;
@@ -17,7 +17,7 @@ fn foo() {
     };
 
     // Please don't ever actually write something like this
-    let _z = static || {
+    let _z = #[coroutine] static || {
         let x = &mut 0;
         *{
             let inner = &mut 1;
diff --git a/tests/ui/coroutine/drop-tracking-parent-expression.rs b/tests/ui/coroutine/drop-tracking-parent-expression.rs
index 4d40192c07a..0f4d99c8936 100644
--- a/tests/ui/coroutine/drop-tracking-parent-expression.rs
+++ b/tests/ui/coroutine/drop-tracking-parent-expression.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines, negative_impls, rustc_attrs)]
+#![feature(coroutines, negative_impls, rustc_attrs, stmt_expr_attributes)]
 
 macro_rules! type_combinations {
     (
@@ -14,7 +14,7 @@ macro_rules! type_combinations {
         // Struct update syntax. This fails because the Client used in the update is considered
         // dropped *after* the yield.
         {
-            let g = move || match drop($name::Client { ..$name::Client::default() }) {
+            let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) {
             //~^ `significant_drop::Client` which is not `Send`
             //~| `insignificant_dtor::Client` which is not `Send`
             //~| `derived_drop::Client` which is not `Send`
@@ -29,7 +29,7 @@ macro_rules! type_combinations {
         // Simple owned value. This works because the Client is considered moved into `drop`,
         // even though the temporary expression doesn't end until after the yield.
         {
-            let g = move || match drop($name::Client::default()) {
+            let g = #[coroutine] move || match drop($name::Client::default()) {
                 _ => yield,
             };
             assert_send(g);
diff --git a/tests/ui/coroutine/drop-tracking-parent-expression.stderr b/tests/ui/coroutine/drop-tracking-parent-expression.stderr
index 21aa35b9579..5f8d8495e4f 100644
--- a/tests/ui/coroutine/drop-tracking-parent-expression.stderr
+++ b/tests/ui/coroutine/drop-tracking-parent-expression.stderr
@@ -13,12 +13,12 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `derived_drop::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}: Send`
+   = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `derived_drop::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}: Send`
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:21:22
    |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `derived_drop::Client` which is not `Send`
+LL |               let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) {
+   |                                                                         ------------------------ has type `derived_drop::Client` which is not `Send`
 ...
 LL |                   _ => yield,
    |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
@@ -53,12 +53,12 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `significant_drop::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}: Send`
+   = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `significant_drop::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}: Send`
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:21:22
    |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `significant_drop::Client` which is not `Send`
+LL |               let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) {
+   |                                                                         ------------------------ has type `significant_drop::Client` which is not `Send`
 ...
 LL |                   _ => yield,
    |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
@@ -93,12 +93,12 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}: Send`
+   = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `insignificant_dtor::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}: Send`
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:21:22
    |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `insignificant_dtor::Client` which is not `Send`
+LL |               let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) {
+   |                                                                         ------------------------ has type `insignificant_dtor::Client` which is not `Send`
 ...
 LL |                   _ => yield,
    |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
diff --git a/tests/ui/coroutine/drop-tracking-yielding-in-match-guards.rs b/tests/ui/coroutine/drop-tracking-yielding-in-match-guards.rs
index 0f94016f11b..43e42fa85f7 100644
--- a/tests/ui/coroutine/drop-tracking-yielding-in-match-guards.rs
+++ b/tests/ui/coroutine/drop-tracking-yielding-in-match-guards.rs
@@ -1,10 +1,10 @@
 //@ build-pass
 //@ edition:2018
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn main() {
-    let _ = static |x: u8| match x {
+    let _ = #[coroutine] static |x: u8| match x {
         y if { yield } == y + 1 => (),
         _ => (),
     };
diff --git a/tests/ui/coroutine/drop-yield-twice.rs b/tests/ui/coroutine/drop-yield-twice.rs
index 015343a2776..7ac1345b2ff 100644
--- a/tests/ui/coroutine/drop-yield-twice.rs
+++ b/tests/ui/coroutine/drop-yield-twice.rs
@@ -1,10 +1,10 @@
-#![feature(negative_impls, coroutines)]
+#![feature(negative_impls, coroutines, stmt_expr_attributes)]
 
 struct Foo(i32);
 impl !Send for Foo {}
 
 fn main() {
-    assert_send(|| { //~ ERROR coroutine cannot be sent between threads safely
+    assert_send(#[coroutine] || { //~ ERROR coroutine cannot be sent between threads safely
         let guard = Foo(42);
         yield;
         drop(guard);
diff --git a/tests/ui/coroutine/drop-yield-twice.stderr b/tests/ui/coroutine/drop-yield-twice.stderr
index c6a9e20b8b5..362c6e943ad 100644
--- a/tests/ui/coroutine/drop-yield-twice.stderr
+++ b/tests/ui/coroutine/drop-yield-twice.stderr
@@ -1,7 +1,7 @@
 error: coroutine cannot be sent between threads safely
   --> $DIR/drop-yield-twice.rs:7:5
    |
-LL | /     assert_send(|| {
+LL | /     assert_send(#[coroutine] || {
 LL | |         let guard = Foo(42);
 LL | |         yield;
 LL | |         drop(guard);
@@ -9,7 +9,7 @@ LL | |         yield;
 LL | |     })
    | |______^ coroutine is not `Send`
    |
-   = help: within `{coroutine@$DIR/drop-yield-twice.rs:7:17: 7:19}`, the trait `Send` is not implemented for `Foo`, which is required by `{coroutine@$DIR/drop-yield-twice.rs:7:17: 7:19}: Send`
+   = help: within `{coroutine@$DIR/drop-yield-twice.rs:7:30: 7:32}`, the trait `Send` is not implemented for `Foo`, which is required by `{coroutine@$DIR/drop-yield-twice.rs:7:30: 7:32}: Send`
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/drop-yield-twice.rs:9:9
    |
diff --git a/tests/ui/coroutine/dropck-resume.rs b/tests/ui/coroutine/dropck-resume.rs
index 07ca4d37aba..df014400f00 100644
--- a/tests/ui/coroutine/dropck-resume.rs
+++ b/tests/ui/coroutine/dropck-resume.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::{Coroutine, CoroutineState};
 use std::pin::Pin;
@@ -16,7 +16,8 @@ fn drop_using_coroutine() -> i32 {
     let z = &mut y;
     let r;
     {
-        let mut g = move |r| {
+        let mut g = #[coroutine]
+        move |r| {
             let _s = SetToNone(r);
             yield;
         };
diff --git a/tests/ui/coroutine/dropck-resume.stderr b/tests/ui/coroutine/dropck-resume.stderr
index aa6e423c760..e9243ffa41e 100644
--- a/tests/ui/coroutine/dropck-resume.stderr
+++ b/tests/ui/coroutine/dropck-resume.stderr
@@ -1,5 +1,5 @@
 error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable
-  --> $DIR/dropck-resume.rs:25:13
+  --> $DIR/dropck-resume.rs:26:13
    |
 LL |     let z = &mut y;
    |             ------ mutable borrow occurs here
diff --git a/tests/ui/coroutine/dropck.rs b/tests/ui/coroutine/dropck.rs
index 450361c8dd0..9331c1fa1d5 100644
--- a/tests/ui/coroutine/dropck.rs
+++ b/tests/ui/coroutine/dropck.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::cell::RefCell;
 use std::ops::Coroutine;
@@ -10,7 +10,8 @@ fn main() {
     let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
     //~^ ERROR `*cell` does not live long enough [E0597]
     // the upvar is the non-dropck `&mut Option<Ref<'a, i32>>`.
-    gen = || {
+    gen = #[coroutine]
+    || {
         // but the coroutine can use it to drop a `Ref<'a, i32>`.
         let _d = ref_.take(); //~ ERROR `ref_` does not live long enough
         yield;
diff --git a/tests/ui/coroutine/dropck.stderr b/tests/ui/coroutine/dropck.stderr
index 241d6dfe0a1..d6cd7c4cd47 100644
--- a/tests/ui/coroutine/dropck.stderr
+++ b/tests/ui/coroutine/dropck.stderr
@@ -16,10 +16,10 @@ LL | }
    = note: values in a scope are dropped in the opposite order they are defined
 
 error[E0597]: `ref_` does not live long enough
-  --> $DIR/dropck.rs:15:18
+  --> $DIR/dropck.rs:16:18
    |
-LL |     gen = || {
-   |           -- value captured here by coroutine
+LL |     || {
+   |     -- value captured here by coroutine
 LL |         // but the coroutine can use it to drop a `Ref<'a, i32>`.
 LL |         let _d = ref_.take();
    |                  ^^^^ borrowed value does not live long enough
diff --git a/tests/ui/coroutine/gen_block.e2024.stderr b/tests/ui/coroutine/gen_block.e2024.stderr
index 2b9eb4a820b..322259cf2f8 100644
--- a/tests/ui/coroutine/gen_block.e2024.stderr
+++ b/tests/ui/coroutine/gen_block.e2024.stderr
@@ -1,5 +1,25 @@
+error[E0658]: the `#[coroutines]` attribute is an experimental feature
+  --> $DIR/gen_block.rs:20:13
+   |
+LL |     let _ = #[coroutine] || yield true;
+   |             ^^^^^^^^^^^^
+   |
+   = 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[E0658]: the `#[coroutines]` attribute is an experimental feature
+  --> $DIR/gen_block.rs:24:13
+   |
+LL |     let _ = #[coroutine] || {};
+   |             ^^^^^^^^^^^^
+   |
+   = 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[E0658]: yield syntax is experimental
-  --> $DIR/gen_block.rs:15:16
+  --> $DIR/gen_block.rs:16:16
    |
 LL |     let _ = || yield true;
    |                ^^^^^^^^^^
@@ -8,13 +28,34 @@ LL |     let _ = || 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/gen_block.rs:16:16
+   |
+LL |     let _ = || yield true;
+   |                ^^^^^^^^^^
+   |
+help: use `#[coroutine]` to make this closure a coroutine
+   |
+LL |     let _ = #[coroutine] || yield true;
+   |             ++++++++++++
+
+error[E0658]: yield syntax is experimental
+  --> $DIR/gen_block.rs:20:29
+   |
+LL |     let _ = #[coroutine] || yield true;
+   |                             ^^^^^^^^^^
+   |
+   = 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[E0282]: type annotations needed
-  --> $DIR/gen_block.rs:6:13
+  --> $DIR/gen_block.rs:7:13
    |
 LL |     let x = gen {};
    |             ^^^^^^ cannot infer type
 
-error: aborting due to 2 previous errors
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0282, E0658.
 For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/coroutine/gen_block.none.stderr b/tests/ui/coroutine/gen_block.none.stderr
index 78a8c5e798a..64fa2be003d 100644
--- a/tests/ui/coroutine/gen_block.none.stderr
+++ b/tests/ui/coroutine/gen_block.none.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found reserved keyword `yield`
-  --> $DIR/gen_block.rs:9:19
+  --> $DIR/gen_block.rs:10:19
    |
 LL |     let y = gen { yield 42 };
    |             ---   ^^^^^ expected identifier, found reserved keyword
@@ -7,25 +7,25 @@ LL |     let y = gen { yield 42 };
    |             while parsing this struct
 
 error[E0422]: cannot find struct, variant or union type `gen` in this scope
-  --> $DIR/gen_block.rs:6:13
+  --> $DIR/gen_block.rs:7:13
    |
 LL |     let x = gen {};
    |             ^^^ not found in this scope
 
 error[E0422]: cannot find struct, variant or union type `gen` in this scope
-  --> $DIR/gen_block.rs:9:13
+  --> $DIR/gen_block.rs:10:13
    |
 LL |     let y = gen { yield 42 };
    |             ^^^ not found in this scope
 
 error[E0422]: cannot find struct, variant or union type `gen` in this scope
-  --> $DIR/gen_block.rs:12:5
+  --> $DIR/gen_block.rs:13:5
    |
 LL |     gen {};
    |     ^^^ not found in this scope
 
 error[E0658]: yield syntax is experimental
-  --> $DIR/gen_block.rs:15:16
+  --> $DIR/gen_block.rs:16:16
    |
 LL |     let _ = || yield true;
    |                ^^^^^^^^^^
@@ -35,17 +35,69 @@ LL |     let _ = || yield true;
    = 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/gen_block.rs:15:16
+  --> $DIR/gen_block.rs:20:29
+   |
+LL |     let _ = #[coroutine] || yield true;
+   |                             ^^^^^^^^^^
+   |
+   = 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[E0658]: the `#[coroutines]` attribute is an experimental feature
+  --> $DIR/gen_block.rs:20:13
+   |
+LL |     let _ = #[coroutine] || yield true;
+   |             ^^^^^^^^^^^^
+   |
+   = 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[E0658]: the `#[coroutines]` attribute is an experimental feature
+  --> $DIR/gen_block.rs:24:13
+   |
+LL |     let _ = #[coroutine] || {};
+   |             ^^^^^^^^^^^^
+   |
+   = 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[E0658]: yield syntax is experimental
+  --> $DIR/gen_block.rs:16:16
+   |
+LL |     let _ = || yield true;
+   |                ^^^^^^^^^^
+   |
+   = 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
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/gen_block.rs:16:16
    |
 LL |     let _ = || yield true;
    |                ^^^^^^^^^^
    |
+help: use `#[coroutine]` to make this closure a coroutine
+   |
+LL |     let _ = #[coroutine] || yield true;
+   |             ++++++++++++
+
+error[E0658]: yield syntax is experimental
+  --> $DIR/gen_block.rs:20:29
+   |
+LL |     let _ = #[coroutine] || yield true;
+   |                             ^^^^^^^^^^
+   |
    = 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
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 6 previous errors
+error: aborting due to 11 previous errors
 
 Some errors have detailed explanations: E0422, E0658.
 For more information about an error, try `rustc --explain E0422`.
diff --git a/tests/ui/coroutine/gen_block.rs b/tests/ui/coroutine/gen_block.rs
index f6a775aa661..7e87a572b90 100644
--- a/tests/ui/coroutine/gen_block.rs
+++ b/tests/ui/coroutine/gen_block.rs
@@ -1,6 +1,7 @@
 //@ revisions: e2024 none
 //@[e2024] compile-flags: --edition 2024 -Zunstable-options
 #![cfg_attr(e2024, feature(gen_blocks))]
+#![feature(stmt_expr_attributes)]
 
 fn main() {
     let x = gen {};
@@ -14,4 +15,12 @@ fn main() {
 
     let _ = || yield true; //[none]~ ERROR yield syntax is experimental
     //~^ ERROR yield syntax is experimental
+    //~^^ ERROR `yield` can only be used in
+
+    let _ = #[coroutine] || yield true; //[none]~ ERROR yield syntax is experimental
+    //~^ ERROR `#[coroutines]` attribute is an experimental feature
+    //~^^ ERROR yield syntax is experimental
+
+    let _ = #[coroutine] || {};
+    //~^ ERROR `#[coroutines]` attribute is an experimental feature
 }
diff --git a/tests/ui/coroutine/issue-102645.rs b/tests/ui/coroutine/issue-102645.rs
index a0263510e13..ccf82c3606a 100644
--- a/tests/ui/coroutine/issue-102645.rs
+++ b/tests/ui/coroutine/issue-102645.rs
@@ -1,11 +1,12 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
 
 fn main() {
     let mut a = 5;
-    let mut b = || {
+    let mut b = #[coroutine]
+    || {
         let d = 6;
         yield;
         _zzz(); // #break
diff --git a/tests/ui/coroutine/issue-102645.stderr b/tests/ui/coroutine/issue-102645.stderr
index 7a3b7f2b04c..ab5e4a8459f 100644
--- a/tests/ui/coroutine/issue-102645.stderr
+++ b/tests/ui/coroutine/issue-102645.stderr
@@ -1,5 +1,5 @@
 error[E0061]: this method takes 1 argument but 0 arguments were supplied
-  --> $DIR/issue-102645.rs:14:22
+  --> $DIR/issue-102645.rs:15:22
    |
 LL |     Pin::new(&mut b).resume();
    |                      ^^^^^^-- an argument of type `()` is missing
diff --git a/tests/ui/coroutine/issue-105084.rs b/tests/ui/coroutine/issue-105084.rs
index 7801f1bcea0..4e40bc127d7 100644
--- a/tests/ui/coroutine/issue-105084.rs
+++ b/tests/ui/coroutine/issue-105084.rs
@@ -11,7 +11,8 @@ fn copy<T: Copy>(x: T) -> T {
 }
 
 fn main() {
-    let mut g = || {
+    let mut g = #[coroutine]
+    || {
         // This is desuraged as 4 stages:
         // - allocate a `*mut u8` with `exchange_malloc`;
         // - create a Box that is ignored for trait computations;
diff --git a/tests/ui/coroutine/issue-105084.stderr b/tests/ui/coroutine/issue-105084.stderr
index c8a6522dbd9..6b1701f0c2a 100644
--- a/tests/ui/coroutine/issue-105084.stderr
+++ b/tests/ui/coroutine/issue-105084.stderr
@@ -1,8 +1,8 @@
 error[E0382]: borrow of moved value: `g`
-  --> $DIR/issue-105084.rs:37:14
+  --> $DIR/issue-105084.rs:38:14
    |
-LL |     let mut g = || {
-   |         ----- move occurs because `g` has type `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}`, which does not implement the `Copy` trait
+LL |     let mut g = #[coroutine]
+   |         ----- move occurs because `g` has type `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}`, which does not implement the `Copy` trait
 ...
 LL |     let mut h = copy(g);
    |                      - value moved here
@@ -22,17 +22,17 @@ help: consider cloning the value if the performance cost is acceptable
 LL |     let mut h = copy(g.clone());
    |                       ++++++++
 
-error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}`
-  --> $DIR/issue-105084.rs:31:17
+error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}`
+  --> $DIR/issue-105084.rs:32:17
    |
-LL |     let mut g = || {
-   |                 -- within this `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}`
+LL |     || {
+   |     -- within this `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}`
 ...
 LL |     let mut h = copy(g);
-   |                 ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}`, the trait `Copy` is not implemented for `Box<(i32, ())>`, which is required by `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}: Copy`
+   |                 ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}`, the trait `Copy` is not implemented for `Box<(i32, ())>`, which is required by `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}: Copy`
    |
 note: coroutine does not implement `Copy` as this value is used across a yield
-  --> $DIR/issue-105084.rs:21:22
+  --> $DIR/issue-105084.rs:22:22
    |
 LL |         Box::new((5, yield));
    |         -------------^^^^^--
diff --git a/tests/ui/coroutine/issue-110929-coroutine-conflict-error-ice.rs b/tests/ui/coroutine/issue-110929-coroutine-conflict-error-ice.rs
index 3d372ac9110..300c8fe6d46 100644
--- a/tests/ui/coroutine/issue-110929-coroutine-conflict-error-ice.rs
+++ b/tests/ui/coroutine/issue-110929-coroutine-conflict-error-ice.rs
@@ -1,11 +1,12 @@
 //@ edition:2021
 //@ check-pass
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn main() {
     let x = &mut ();
     || {
-        let _c = || yield *&mut *x;
+        let _c = #[coroutine]
+        || yield *&mut *x;
         || _ = &mut *x;
     };
 }
diff --git a/tests/ui/coroutine/issue-113279.rs b/tests/ui/coroutine/issue-113279.rs
index f251c924c13..98617af105c 100644
--- a/tests/ui/coroutine/issue-113279.rs
+++ b/tests/ui/coroutine/issue-113279.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 // `foo` attempts to dereference `""`, which results in an error being reported. Later, the
 // coroutine transform for `foo` then produces a union which contains a `str` type - unions should
@@ -9,7 +9,8 @@
 // makes sure that doesn't happen again.
 
 fn foo() {
-    let _y = static || {
+    let _y = #[coroutine]
+    static || {
         let x = &mut 0;
         *{
             yield;
diff --git a/tests/ui/coroutine/issue-113279.stderr b/tests/ui/coroutine/issue-113279.stderr
index cc9b64ef9ac..a80fe670188 100644
--- a/tests/ui/coroutine/issue-113279.stderr
+++ b/tests/ui/coroutine/issue-113279.stderr
@@ -1,11 +1,11 @@
 error[E0161]: cannot move a value of type `str`
-  --> $DIR/issue-113279.rs:17:20
+  --> $DIR/issue-113279.rs:18:20
    |
 LL |         } += match { *"" }.len() {
    |                    ^^^^^^^ the size of `str` cannot be statically determined
 
 error[E0507]: cannot move out of a shared reference
-  --> $DIR/issue-113279.rs:17:22
+  --> $DIR/issue-113279.rs:18:22
    |
 LL |         } += match { *"" }.len() {
    |                      ^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
diff --git a/tests/ui/coroutine/issue-44197.rs b/tests/ui/coroutine/issue-44197.rs
index e18bcc2c996..0240f7a7eaa 100644
--- a/tests/ui/coroutine/issue-44197.rs
+++ b/tests/ui/coroutine/issue-44197.rs
@@ -10,7 +10,7 @@ fn foo(_: &str) -> String {
 }
 
 fn bar(baz: String) -> impl Coroutine<(), Yield = String, Return = ()> {
-    move || {
+    #[coroutine] move || {
         yield foo(&baz);
     }
 }
@@ -20,7 +20,7 @@ fn foo2(_: &str) -> Result<String, ()> {
 }
 
 fn bar2(baz: String) -> impl Coroutine<(), Yield = String, Return = ()> {
-    move || {
+    #[coroutine] move || {
         if let Ok(quux) = foo2(&baz) {
             yield quux;
         }
diff --git a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.rs b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.rs
index dab9c81bc8f..d90886b6b1d 100644
--- a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.rs
+++ b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.rs
@@ -1,7 +1,8 @@
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn main() {
-    let _ = || {
+    let _ = #[coroutine]
+    || {
         *(1 as *mut u32) = 42;
         //~^ ERROR dereference of raw pointer is unsafe
         yield;
diff --git a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr
index 19949b42939..f99c295bb9e 100644
--- a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr
+++ b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr
@@ -1,5 +1,5 @@
 error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
-  --> $DIR/issue-45729-unsafe-in-coroutine.rs:5:9
+  --> $DIR/issue-45729-unsafe-in-coroutine.rs:6:9
    |
 LL |         *(1 as *mut u32) = 42;
    |         ^^^^^^^^^^^^^^^^ dereference of raw pointer
diff --git a/tests/ui/coroutine/issue-48048.rs b/tests/ui/coroutine/issue-48048.rs
index b61b7c77072..75664f20198 100644
--- a/tests/ui/coroutine/issue-48048.rs
+++ b/tests/ui/coroutine/issue-48048.rs
@@ -3,7 +3,7 @@
 fn main() {
     let x = (|_| {},);
 
-    || {
+    #[coroutine] || {
         let x = x;
 
         x.0({ //~ ERROR borrow may still be in use when coroutine yields
diff --git a/tests/ui/coroutine/issue-52304.rs b/tests/ui/coroutine/issue-52304.rs
index 01ed181ab1d..552bc0028ee 100644
--- a/tests/ui/coroutine/issue-52304.rs
+++ b/tests/ui/coroutine/issue-52304.rs
@@ -5,6 +5,7 @@
 use std::ops::Coroutine;
 
 pub fn example() -> impl Coroutine {
+    #[coroutine]
     || yield &1
 }
 
diff --git a/tests/ui/coroutine/issue-52398.rs b/tests/ui/coroutine/issue-52398.rs
index 826ce6b9d9b..f8b2faf4eab 100644
--- a/tests/ui/coroutine/issue-52398.rs
+++ b/tests/ui/coroutine/issue-52398.rs
@@ -14,14 +14,14 @@ impl A {
 fn main() {
     // Test that the MIR local with type &A created for the auto-borrow adjustment
     // is caught by typeck
-    move || { //~ WARN unused coroutine that must be used
+    #[coroutine] move || { //~ WARN unused coroutine that must be used
         A.test(yield);
     };
 
     // Test that the std::cell::Ref temporary returned from the `borrow` call
     // is caught by typeck
     let y = RefCell::new(true);
-    static move || { //~ WARN unused coroutine that must be used
+    #[coroutine] static move || { //~ WARN unused coroutine that must be used
         yield *y.borrow();
         return "Done";
     };
diff --git a/tests/ui/coroutine/issue-52398.stderr b/tests/ui/coroutine/issue-52398.stderr
index 18d816da4c6..806690cc332 100644
--- a/tests/ui/coroutine/issue-52398.stderr
+++ b/tests/ui/coroutine/issue-52398.stderr
@@ -1,7 +1,8 @@
 warning: unused coroutine that must be used
-  --> $DIR/issue-52398.rs:17:5
+  --> $DIR/issue-52398.rs:17:18
    |
-LL | /     move || {
+LL |       #[coroutine] move || {
+   |  __________________^
 LL | |         A.test(yield);
 LL | |     };
    | |_____^
@@ -10,9 +11,10 @@ LL | |     };
    = note: `#[warn(unused_must_use)]` on by default
 
 warning: unused coroutine that must be used
-  --> $DIR/issue-52398.rs:24:5
+  --> $DIR/issue-52398.rs:24:18
    |
-LL | /     static move || {
+LL |       #[coroutine] static move || {
+   |  __________________^
 LL | |         yield *y.borrow();
 LL | |         return "Done";
 LL | |     };
diff --git a/tests/ui/coroutine/issue-53548.rs b/tests/ui/coroutine/issue-53548.rs
index 6d55994137f..3b8dff2be28 100644
--- a/tests/ui/coroutine/issue-53548.rs
+++ b/tests/ui/coroutine/issue-53548.rs
@@ -17,7 +17,7 @@
 //
 //@ check-pass
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 use std::cell::RefCell;
 use std::rc::Rc;
@@ -29,7 +29,7 @@ struct Store<C> {
 }
 
 fn main() {
-    Box::new(static move || {
+    Box::new(#[coroutine] static move || {
         let store = Store::<Box<dyn Trait>> {
             inner: Default::default(),
         };
diff --git a/tests/ui/coroutine/issue-57017.rs b/tests/ui/coroutine/issue-57017.rs
index b83d916932a..19cd80ab4a6 100644
--- a/tests/ui/coroutine/issue-57017.rs
+++ b/tests/ui/coroutine/issue-57017.rs
@@ -1,5 +1,5 @@
 //@ build-pass
-#![feature(coroutines, negative_impls)]
+#![feature(coroutines, negative_impls, stmt_expr_attributes)]
 #![allow(dropping_references, dropping_copy_types)]
 
 macro_rules! type_combinations {
@@ -21,7 +21,7 @@ macro_rules! type_combinations {
 
         // This is the same bug as issue 57017, but using yield instead of await
         {
-            let g = move || match drop(&$name::unsync::Client::default()) {
+            let g = #[coroutine] move || match drop(&$name::unsync::Client::default()) {
                 _status => yield,
             };
             assert_send(g);
@@ -30,7 +30,7 @@ macro_rules! type_combinations {
         // This tests that `Client` is properly considered to be dropped after moving it into the
         // function.
         {
-            let g = move || match drop($name::unsend::Client::default()) {
+            let g = #[coroutine] move || match drop($name::unsend::Client::default()) {
                 _status => yield,
             };
             assert_send(g);
diff --git a/tests/ui/coroutine/issue-57084.rs b/tests/ui/coroutine/issue-57084.rs
index 51b0c8e1de9..2df60550e03 100644
--- a/tests/ui/coroutine/issue-57084.rs
+++ b/tests/ui/coroutine/issue-57084.rs
@@ -8,7 +8,7 @@ use std::ops::Coroutine;
 fn with<F>(f: F) -> impl Coroutine<Yield=(), Return=()>
 where F: Fn() -> ()
 {
-    move || {
+    #[coroutine] move || {
         loop {
             match f() {
                 _ => yield,
@@ -19,7 +19,7 @@ where F: Fn() -> ()
 
 fn main() {
     let data = &vec![1];
-    || { //~ WARN unused coroutine that must be used
+    #[coroutine] || { //~ WARN unused coroutine that must be used
         let _to_pin = with(move || println!("{:p}", data));
         loop {
             yield
diff --git a/tests/ui/coroutine/issue-57084.stderr b/tests/ui/coroutine/issue-57084.stderr
index 9f5b79a6ae8..81bd27da919 100644
--- a/tests/ui/coroutine/issue-57084.stderr
+++ b/tests/ui/coroutine/issue-57084.stderr
@@ -1,7 +1,8 @@
 warning: unused coroutine that must be used
-  --> $DIR/issue-57084.rs:22:5
+  --> $DIR/issue-57084.rs:22:18
    |
-LL | /     || {
+LL |       #[coroutine] || {
+   |  __________________^
 LL | |         let _to_pin = with(move || println!("{:p}", data));
 LL | |         loop {
 LL | |             yield
diff --git a/tests/ui/coroutine/issue-57478.rs b/tests/ui/coroutine/issue-57478.rs
index 5e479aaa9c1..494c2ee9843 100644
--- a/tests/ui/coroutine/issue-57478.rs
+++ b/tests/ui/coroutine/issue-57478.rs
@@ -1,16 +1,19 @@
 //@ check-pass
 
-#![feature(negative_impls, coroutines)]
+#![feature(negative_impls, coroutines, stmt_expr_attributes)]
 
 struct Foo;
 impl !Send for Foo {}
 
 fn main() {
-    assert_send(|| {
-        let guard = Foo;
-        drop(guard);
-        yield;
-    })
+    assert_send(
+        #[coroutine]
+        || {
+            let guard = Foo;
+            drop(guard);
+            yield;
+        },
+    )
 }
 
 fn assert_send<T: Send>(_: T) {}
diff --git a/tests/ui/coroutine/issue-58888.rs b/tests/ui/coroutine/issue-58888.rs
index ce45f22dd6e..6266f97ce8c 100644
--- a/tests/ui/coroutine/issue-58888.rs
+++ b/tests/ui/coroutine/issue-58888.rs
@@ -13,7 +13,7 @@ impl Database {
     }
 
     fn check_connection(&self) -> impl Coroutine<Yield = (), Return = ()> + '_ {
-        move || {
+        #[coroutine] move || {
             let iter = self.get_connection();
             for i in iter {
                 yield i
diff --git a/tests/ui/coroutine/issue-61442-stmt-expr-with-drop.rs b/tests/ui/coroutine/issue-61442-stmt-expr-with-drop.rs
index 6280b777201..6f513c250a5 100644
--- a/tests/ui/coroutine/issue-61442-stmt-expr-with-drop.rs
+++ b/tests/ui/coroutine/issue-61442-stmt-expr-with-drop.rs
@@ -4,7 +4,7 @@
 //@ check-pass
 //@ edition:2018
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 
@@ -14,12 +14,14 @@ async fn drop_and_await() {
 }
 
 fn drop_and_yield() {
-    let x = || {
+    let x = #[coroutine]
+    || {
         String::new();
         yield;
     };
     Box::pin(x).as_mut().resume(());
-    let y = static || {
+    let y = #[coroutine]
+    static || {
         String::new();
         yield;
     };
diff --git a/tests/ui/coroutine/issue-64620-yield-array-element.rs b/tests/ui/coroutine/issue-64620-yield-array-element.rs
index a9307d306a6..0d898d014e8 100644
--- a/tests/ui/coroutine/issue-64620-yield-array-element.rs
+++ b/tests/ui/coroutine/issue-64620-yield-array-element.rs
@@ -4,6 +4,7 @@
 
 pub fn crash(arr: [usize; 1]) {
     yield arr[0]; //~ ERROR: yield expression outside of coroutine literal
+    //~^ ERROR: `yield` can only be used in
 }
 
 fn main() {}
diff --git a/tests/ui/coroutine/issue-64620-yield-array-element.stderr b/tests/ui/coroutine/issue-64620-yield-array-element.stderr
index 347532fb719..1c030c5248e 100644
--- a/tests/ui/coroutine/issue-64620-yield-array-element.stderr
+++ b/tests/ui/coroutine/issue-64620-yield-array-element.stderr
@@ -1,9 +1,20 @@
+error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/issue-64620-yield-array-element.rs:6:5
+   |
+LL |     yield arr[0];
+   |     ^^^^^^^^^^^^
+   |
+help: use `#[coroutine]` to make this closure a coroutine
+   |
+LL | #[coroutine] pub fn crash(arr: [usize; 1]) {
+   | ++++++++++++
+
 error[E0627]: yield expression outside of coroutine literal
   --> $DIR/issue-64620-yield-array-element.rs:6:5
    |
 LL |     yield arr[0];
    |     ^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0627`.
diff --git a/tests/ui/coroutine/issue-68112.rs b/tests/ui/coroutine/issue-68112.rs
index ccec2acc976..b296772c905 100644
--- a/tests/ui/coroutine/issue-68112.rs
+++ b/tests/ui/coroutine/issue-68112.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::{
     cell::RefCell,
@@ -30,7 +30,7 @@ fn make_non_send_coroutine() -> impl Coroutine<Return = Arc<RefCell<i32>>> {
 }
 
 fn test1() {
-    let send_gen = || {
+    let send_gen = #[coroutine] || {
         let _non_send_gen = make_non_send_coroutine();
         //~^ NOTE not `Send`
         yield;
@@ -46,7 +46,7 @@ fn test1() {
 pub fn make_gen2<T>(t: T) -> impl Coroutine<Return = T> {
 //~^ NOTE appears within the type
 //~| NOTE expansion of desugaring
-    || { //~ NOTE used within this coroutine
+    #[coroutine] || { //~ NOTE used within this coroutine
         yield;
         t
     }
@@ -57,7 +57,7 @@ fn make_non_send_coroutine2() -> impl Coroutine<Return = Arc<RefCell<i32>>> { //
 }
 
 fn test2() {
-    let send_gen = || { //~ NOTE used within this coroutine
+    let send_gen = #[coroutine] || { //~ NOTE used within this coroutine
         let _non_send_gen = make_non_send_coroutine2();
         yield;
     };
diff --git a/tests/ui/coroutine/issue-68112.stderr b/tests/ui/coroutine/issue-68112.stderr
index 443195d36a3..bcfcb5ec6e6 100644
--- a/tests/ui/coroutine/issue-68112.stderr
+++ b/tests/ui/coroutine/issue-68112.stderr
@@ -4,7 +4,7 @@ error: coroutine cannot be sent between threads safely
 LL |     require_send(send_gen);
    |     ^^^^^^^^^^^^^^^^^^^^^^ coroutine is not `Send`
    |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{coroutine@$DIR/issue-68112.rs:33:20: 33:22}: Send`
+   = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{coroutine@$DIR/issue-68112.rs:33:33: 33:35}: Send`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/issue-68112.rs:36:9
@@ -26,14 +26,14 @@ error[E0277]: `RefCell<i32>` cannot be shared between threads safely
 LL |     require_send(send_gen);
    |     ^^^^^^^^^^^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
    |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{coroutine@$DIR/issue-68112.rs:60:20: 60:22}: Send`
+   = help: the trait `Sync` is not implemented for `RefCell<i32>`, which is required by `{coroutine@$DIR/issue-68112.rs:60:33: 60:35}: Send`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this coroutine
-  --> $DIR/issue-68112.rs:49:5
+  --> $DIR/issue-68112.rs:49:18
    |
-LL |     || {
-   |     ^^
+LL |     #[coroutine] || {
+   |                  ^^
 note: required because it appears within the type `impl Coroutine<Return = Arc<RefCell<i32>>>`
   --> $DIR/issue-68112.rs:46:30
    |
@@ -45,10 +45,10 @@ note: required because it appears within the type `impl Coroutine<Return = Arc<R
 LL | fn make_non_send_coroutine2() -> impl Coroutine<Return = Arc<RefCell<i32>>> {
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: required because it's used within this coroutine
-  --> $DIR/issue-68112.rs:60:20
+  --> $DIR/issue-68112.rs:60:33
    |
-LL |     let send_gen = || {
-   |                    ^^
+LL |     let send_gen = #[coroutine] || {
+   |                                 ^^
 note: required by a bound in `require_send`
   --> $DIR/issue-68112.rs:22:25
    |
diff --git a/tests/ui/coroutine/issue-69017.rs b/tests/ui/coroutine/issue-69017.rs
index 09bbf63a986..bf69e1dfdb1 100644
--- a/tests/ui/coroutine/issue-69017.rs
+++ b/tests/ui/coroutine/issue-69017.rs
@@ -10,6 +10,7 @@
 use std::ops::Coroutine;
 
 fn gen() -> impl Coroutine<usize> {
+    #[coroutine]
     |_: usize| {
         println!("-> {}", yield);
     }
diff --git a/tests/ui/coroutine/issue-69039.rs b/tests/ui/coroutine/issue-69039.rs
index fd12414c3d8..13cb50e5828 100644
--- a/tests/ui/coroutine/issue-69039.rs
+++ b/tests/ui/coroutine/issue-69039.rs
@@ -9,6 +9,7 @@ fn mkstr(my_name: String, my_mood: String) -> String {
 }
 
 fn my_scenario() -> impl Coroutine<String, Yield = &'static str, Return = String> {
+    #[coroutine]
     |_arg: String| {
         let my_name = yield "What is your name?";
         let my_mood = yield "How are you feeling?";
diff --git a/tests/ui/coroutine/issue-87142.rs b/tests/ui/coroutine/issue-87142.rs
index f5c3805842c..6c22ba3dd75 100644
--- a/tests/ui/coroutine/issue-87142.rs
+++ b/tests/ui/coroutine/issue-87142.rs
@@ -22,6 +22,7 @@ pub struct Context<G: 'static + CoroutineProviderAlt> {
 impl CoroutineProviderAlt for () {
     type Coro = impl Coroutine<(), Return = (), Yield = ()>;
     fn start(ctx: Context<Self>) -> Self::Coro {
+        #[coroutine]
         move || {
             match ctx {
                 _ => (),
diff --git a/tests/ui/coroutine/issue-88653.rs b/tests/ui/coroutine/issue-88653.rs
index ec4c2054758..3afd12a2093 100644
--- a/tests/ui/coroutine/issue-88653.rs
+++ b/tests/ui/coroutine/issue-88653.rs
@@ -11,6 +11,7 @@ fn foo(bar: bool) -> impl Coroutine<(bool,)> {
     //~| NOTE: expected coroutine signature `fn((bool,)) -> _`
     //~| NOTE: in this expansion of desugaring of `impl Trait`
     //~| NOTE: in this expansion of desugaring of `impl Trait`
+    #[coroutine]
     |bar| {
         //~^ NOTE: found signature defined here
         if bar {
diff --git a/tests/ui/coroutine/issue-91477.rs b/tests/ui/coroutine/issue-91477.rs
index c98546f7971..c215fd7948f 100644
--- a/tests/ui/coroutine/issue-91477.rs
+++ b/tests/ui/coroutine/issue-91477.rs
@@ -2,6 +2,7 @@
 
 fn foo() -> impl Sized {
     yield 1; //~ ERROR E0627
+    //~^ ERROR: `yield` can only be used in
 }
 
 fn main() {}
diff --git a/tests/ui/coroutine/issue-91477.stderr b/tests/ui/coroutine/issue-91477.stderr
index ca8e43d8a26..5e2151c4c35 100644
--- a/tests/ui/coroutine/issue-91477.stderr
+++ b/tests/ui/coroutine/issue-91477.stderr
@@ -1,9 +1,20 @@
+error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/issue-91477.rs:4:5
+   |
+LL |     yield 1;
+   |     ^^^^^^^
+   |
+help: use `#[coroutine]` to make this closure a coroutine
+   |
+LL | #[coroutine] fn foo() -> impl Sized {
+   | ++++++++++++
+
 error[E0627]: yield expression outside of coroutine literal
   --> $DIR/issue-91477.rs:4:5
    |
 LL |     yield 1;
    |     ^^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0627`.
diff --git a/tests/ui/coroutine/iterator-count.rs b/tests/ui/coroutine/iterator-count.rs
index bb202ab2d33..1ca8ceaed2a 100644
--- a/tests/ui/coroutine/iterator-count.rs
+++ b/tests/ui/coroutine/iterator-count.rs
@@ -21,6 +21,7 @@ impl<T: Coroutine<(), Return = ()> + Unpin> Iterator for W<T> {
 }
 
 fn test() -> impl Coroutine<(), Return = (), Yield = u8> + Unpin {
+    #[coroutine]
     || {
         for i in 1..6 {
             yield i
@@ -32,6 +33,7 @@ fn main() {
     let end = 11;
 
     let closure_test = |start| {
+        #[coroutine]
         move || {
             for i in start..end {
                 yield i
diff --git a/tests/ui/coroutine/live-upvar-across-yield.rs b/tests/ui/coroutine/live-upvar-across-yield.rs
index 86c4716c951..d13d480dcdc 100644
--- a/tests/ui/coroutine/live-upvar-across-yield.rs
+++ b/tests/ui/coroutine/live-upvar-across-yield.rs
@@ -1,13 +1,13 @@
 //@ run-pass
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
 
 fn main() {
     let b = |_| 3;
-    let mut a = || {
+    let mut a = #[coroutine] || {
         b(yield);
     };
     Pin::new(&mut a).resume(());
diff --git a/tests/ui/coroutine/match-bindings.rs b/tests/ui/coroutine/match-bindings.rs
index 9ea1deaab36..2a0cd9af9f3 100644
--- a/tests/ui/coroutine/match-bindings.rs
+++ b/tests/ui/coroutine/match-bindings.rs
@@ -9,7 +9,7 @@ enum Enum {
 }
 
 fn main() {
-    || { //~ WARN unused coroutine that must be used
+    #[coroutine] || { //~ WARN unused coroutine that must be used
         loop {
             if let true = true {
                 match Enum::A(String::new()) {
diff --git a/tests/ui/coroutine/match-bindings.stderr b/tests/ui/coroutine/match-bindings.stderr
index a7aa6eadb95..5525bfed116 100644
--- a/tests/ui/coroutine/match-bindings.stderr
+++ b/tests/ui/coroutine/match-bindings.stderr
@@ -1,7 +1,8 @@
 warning: unused coroutine that must be used
-  --> $DIR/match-bindings.rs:12:5
+  --> $DIR/match-bindings.rs:12:18
    |
-LL | /     || {
+LL |       #[coroutine] || {
+   |  __________________^
 LL | |         loop {
 LL | |             if let true = true {
 LL | |                 match Enum::A(String::new()) {
diff --git a/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed b/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed
new file mode 100644
index 00000000000..128f09a1184
--- /dev/null
+++ b/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed
@@ -0,0 +1,8 @@
+//@ run-rustfix
+
+#![feature(coroutines, gen_blocks, stmt_expr_attributes)]
+
+fn main() {
+    let _ = #[coroutine] || yield;
+    //~^ ERROR `yield` can only be used
+}
diff --git a/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs b/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs
new file mode 100644
index 00000000000..dc952591496
--- /dev/null
+++ b/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs
@@ -0,0 +1,8 @@
+//@ run-rustfix
+
+#![feature(coroutines, gen_blocks, stmt_expr_attributes)]
+
+fn main() {
+    let _ = || yield;
+    //~^ ERROR `yield` can only be used
+}
diff --git a/tests/ui/coroutine/missing_coroutine_attr_suggestion.stderr b/tests/ui/coroutine/missing_coroutine_attr_suggestion.stderr
new file mode 100644
index 00000000000..8d92471a361
--- /dev/null
+++ b/tests/ui/coroutine/missing_coroutine_attr_suggestion.stderr
@@ -0,0 +1,13 @@
+error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/missing_coroutine_attr_suggestion.rs:6:16
+   |
+LL |     let _ = || yield;
+   |                ^^^^^
+   |
+help: use `#[coroutine]` to make this closure a coroutine
+   |
+LL |     let _ = #[coroutine] || yield;
+   |             ++++++++++++
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/coroutine/nested_coroutine.rs b/tests/ui/coroutine/nested_coroutine.rs
index 7ff97abf4bb..2c12ab2adad 100644
--- a/tests/ui/coroutine/nested_coroutine.rs
+++ b/tests/ui/coroutine/nested_coroutine.rs
@@ -1,13 +1,15 @@
 //@ run-pass
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::{Coroutine, CoroutineState};
 use std::pin::Pin;
 
 fn main() {
-    let _coroutine = || {
-        let mut sub_coroutine = || {
+    let _coroutine = #[coroutine]
+    || {
+        let mut sub_coroutine = #[coroutine]
+        || {
             yield 2;
         };
 
diff --git a/tests/ui/coroutine/niche-in-coroutine.rs b/tests/ui/coroutine/niche-in-coroutine.rs
index 45b920ab927..117ee9e6f03 100644
--- a/tests/ui/coroutine/niche-in-coroutine.rs
+++ b/tests/ui/coroutine/niche-in-coroutine.rs
@@ -2,7 +2,7 @@
 
 //@ run-pass
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 use std::mem::size_of_val;
 
@@ -10,7 +10,7 @@ fn take<T>(_: T) {}
 
 fn main() {
     let x = false;
-    let gen1 = || {
+    let gen1 = #[coroutine] || {
         yield;
         take(x);
     };
diff --git a/tests/ui/coroutine/non-static-is-unpin.rs b/tests/ui/coroutine/non-static-is-unpin.rs
index 616a78d5fe2..b28bf197714 100644
--- a/tests/ui/coroutine/non-static-is-unpin.rs
+++ b/tests/ui/coroutine/non-static-is-unpin.rs
@@ -3,7 +3,7 @@
 //@[next] compile-flags: -Znext-solver
 //@ run-pass
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 #![allow(dropping_copy_types)]
 
 use std::marker::PhantomPinned;
@@ -14,7 +14,7 @@ fn assert_unpin<G: Unpin>(_: G) {
 fn main() {
     // Even though this coroutine holds a `PhantomPinned` in its environment, it
     // remains `Unpin`.
-    assert_unpin(|| {
+    assert_unpin(#[coroutine] || {
         let pinned = PhantomPinned;
         yield;
         drop(pinned);
diff --git a/tests/ui/coroutine/not-send-sync.rs b/tests/ui/coroutine/not-send-sync.rs
index dd6182c10de..a46dcd14e88 100644
--- a/tests/ui/coroutine/not-send-sync.rs
+++ b/tests/ui/coroutine/not-send-sync.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 #![feature(negative_impls)]
 
 struct NotSend;
@@ -11,14 +11,14 @@ fn main() {
     fn assert_sync<T: Sync>(_: T) {}
     fn assert_send<T: Send>(_: T) {}
 
-    assert_sync(|| {
+    assert_sync(#[coroutine] || {
         //~^ ERROR: coroutine cannot be shared between threads safely
         let a = NotSync;
         yield;
         drop(a);
     });
 
-    assert_send(|| {
+    assert_send(#[coroutine] || {
         //~^ ERROR: coroutine cannot be sent between threads safely
         let a = NotSend;
         yield;
diff --git a/tests/ui/coroutine/not-send-sync.stderr b/tests/ui/coroutine/not-send-sync.stderr
index 9228340c710..0f9cbdec130 100644
--- a/tests/ui/coroutine/not-send-sync.stderr
+++ b/tests/ui/coroutine/not-send-sync.stderr
@@ -1,7 +1,7 @@
 error: coroutine cannot be shared between threads safely
   --> $DIR/not-send-sync.rs:14:5
    |
-LL | /     assert_sync(|| {
+LL | /     assert_sync(#[coroutine] || {
 LL | |
 LL | |         let a = NotSync;
 LL | |         yield;
@@ -9,7 +9,7 @@ LL | |         drop(a);
 LL | |     });
    | |______^ coroutine is not `Sync`
    |
-   = help: within `{coroutine@$DIR/not-send-sync.rs:14:17: 14:19}`, the trait `Sync` is not implemented for `NotSync`, which is required by `{coroutine@$DIR/not-send-sync.rs:14:17: 14:19}: Sync`
+   = help: within `{coroutine@$DIR/not-send-sync.rs:14:30: 14:32}`, the trait `Sync` is not implemented for `NotSync`, which is required by `{coroutine@$DIR/not-send-sync.rs:14:30: 14:32}: Sync`
 note: coroutine is not `Sync` as this value is used across a yield
   --> $DIR/not-send-sync.rs:17:9
    |
@@ -26,7 +26,7 @@ LL |     fn assert_sync<T: Sync>(_: T) {}
 error: coroutine cannot be sent between threads safely
   --> $DIR/not-send-sync.rs:21:5
    |
-LL | /     assert_send(|| {
+LL | /     assert_send(#[coroutine] || {
 LL | |
 LL | |         let a = NotSend;
 LL | |         yield;
@@ -34,7 +34,7 @@ LL | |         drop(a);
 LL | |     });
    | |______^ coroutine is not `Send`
    |
-   = help: within `{coroutine@$DIR/not-send-sync.rs:21:17: 21:19}`, the trait `Send` is not implemented for `NotSend`, which is required by `{coroutine@$DIR/not-send-sync.rs:21:17: 21:19}: Send`
+   = help: within `{coroutine@$DIR/not-send-sync.rs:21:30: 21:32}`, the trait `Send` is not implemented for `NotSend`, which is required by `{coroutine@$DIR/not-send-sync.rs:21:30: 21:32}: Send`
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/not-send-sync.rs:24:9
    |
diff --git a/tests/ui/coroutine/overlap-locals.rs b/tests/ui/coroutine/overlap-locals.rs
index eea8595ed06..9cfa6e2a76d 100644
--- a/tests/ui/coroutine/overlap-locals.rs
+++ b/tests/ui/coroutine/overlap-locals.rs
@@ -1,9 +1,10 @@
 //@ run-pass
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn main() {
-    let a = || {
+    let a = #[coroutine]
+    || {
         {
             let w: i32 = 4;
             yield;
diff --git a/tests/ui/coroutine/panic-drops-resume.rs b/tests/ui/coroutine/panic-drops-resume.rs
index 6d026e6edc8..b23666b7885 100644
--- a/tests/ui/coroutine/panic-drops-resume.rs
+++ b/tests/ui/coroutine/panic-drops-resume.rs
@@ -3,7 +3,7 @@
 //@ run-pass
 //@ needs-unwind
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::panic::{catch_unwind, AssertUnwindSafe};
@@ -21,7 +21,7 @@ impl Drop for Dropper {
 }
 
 fn main() {
-    let mut gen = |_arg| {
+    let mut gen = #[coroutine] |_arg| {
         if true {
             panic!();
         }
diff --git a/tests/ui/coroutine/panic-drops.rs b/tests/ui/coroutine/panic-drops.rs
index c99abdc7246..8c2cf560f2a 100644
--- a/tests/ui/coroutine/panic-drops.rs
+++ b/tests/ui/coroutine/panic-drops.rs
@@ -1,8 +1,7 @@
 //@ run-pass
 //@ needs-unwind
 
-
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::panic;
@@ -25,7 +24,8 @@ fn bool_true() -> bool {
 
 fn main() {
     let b = B;
-    let mut foo = || {
+    let mut foo = #[coroutine]
+    || {
         if bool_true() {
             panic!();
         }
@@ -34,13 +34,12 @@ fn main() {
     };
 
     assert_eq!(A.load(Ordering::SeqCst), 0);
-    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        Pin::new(&mut foo).resume(())
-    }));
+    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| Pin::new(&mut foo).resume(())));
     assert!(res.is_err());
     assert_eq!(A.load(Ordering::SeqCst), 1);
 
-    let mut foo = || {
+    let mut foo = #[coroutine]
+    || {
         if bool_true() {
             panic!();
         }
@@ -49,9 +48,7 @@ fn main() {
     };
 
     assert_eq!(A.load(Ordering::SeqCst), 1);
-    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        Pin::new(&mut foo).resume(())
-    }));
+    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| Pin::new(&mut foo).resume(())));
     assert!(res.is_err());
     assert_eq!(A.load(Ordering::SeqCst), 1);
 }
diff --git a/tests/ui/coroutine/panic-safe.rs b/tests/ui/coroutine/panic-safe.rs
index 89dd09bf520..6b9b4cb33c3 100644
--- a/tests/ui/coroutine/panic-safe.rs
+++ b/tests/ui/coroutine/panic-safe.rs
@@ -2,14 +2,14 @@
 //@ needs-unwind
 
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
 use std::panic;
 
 fn main() {
-    let mut foo = || {
+    let mut foo = #[coroutine] || {
         if true {
             panic!();
         }
diff --git a/tests/ui/coroutine/parent-expression.rs b/tests/ui/coroutine/parent-expression.rs
index 4d40192c07a..0f4d99c8936 100644
--- a/tests/ui/coroutine/parent-expression.rs
+++ b/tests/ui/coroutine/parent-expression.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines, negative_impls, rustc_attrs)]
+#![feature(coroutines, negative_impls, rustc_attrs, stmt_expr_attributes)]
 
 macro_rules! type_combinations {
     (
@@ -14,7 +14,7 @@ macro_rules! type_combinations {
         // Struct update syntax. This fails because the Client used in the update is considered
         // dropped *after* the yield.
         {
-            let g = move || match drop($name::Client { ..$name::Client::default() }) {
+            let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) {
             //~^ `significant_drop::Client` which is not `Send`
             //~| `insignificant_dtor::Client` which is not `Send`
             //~| `derived_drop::Client` which is not `Send`
@@ -29,7 +29,7 @@ macro_rules! type_combinations {
         // Simple owned value. This works because the Client is considered moved into `drop`,
         // even though the temporary expression doesn't end until after the yield.
         {
-            let g = move || match drop($name::Client::default()) {
+            let g = #[coroutine] move || match drop($name::Client::default()) {
                 _ => yield,
             };
             assert_send(g);
diff --git a/tests/ui/coroutine/parent-expression.stderr b/tests/ui/coroutine/parent-expression.stderr
index 5b3737069e6..2d817f1bfd9 100644
--- a/tests/ui/coroutine/parent-expression.stderr
+++ b/tests/ui/coroutine/parent-expression.stderr
@@ -13,12 +13,12 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `derived_drop::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}: Send`
+   = help: within `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `derived_drop::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}: Send`
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:21:22
    |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `derived_drop::Client` which is not `Send`
+LL |               let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) {
+   |                                                                         ------------------------ has type `derived_drop::Client` which is not `Send`
 ...
 LL |                   _ => yield,
    |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
@@ -53,12 +53,12 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `significant_drop::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}: Send`
+   = help: within `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `significant_drop::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}: Send`
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:21:22
    |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `significant_drop::Client` which is not `Send`
+LL |               let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) {
+   |                                                                         ------------------------ has type `significant_drop::Client` which is not `Send`
 ...
 LL |                   _ => yield,
    |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
@@ -93,12 +93,12 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}: Send`
+   = help: within `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `insignificant_dtor::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}: Send`
 note: coroutine is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:21:22
    |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `insignificant_dtor::Client` which is not `Send`
+LL |               let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) {
+   |                                                                         ------------------------ has type `insignificant_dtor::Client` which is not `Send`
 ...
 LL |                   _ => yield,
    |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
diff --git a/tests/ui/coroutine/partial-drop.rs b/tests/ui/coroutine/partial-drop.rs
index ba13544712f..9efb551c9c1 100644
--- a/tests/ui/coroutine/partial-drop.rs
+++ b/tests/ui/coroutine/partial-drop.rs
@@ -1,5 +1,5 @@
 //@ check-pass
-#![feature(negative_impls, coroutines)]
+#![feature(negative_impls, coroutines, stmt_expr_attributes)]
 
 struct Foo;
 impl !Send for Foo {}
@@ -10,25 +10,34 @@ struct Bar {
 }
 
 fn main() {
-    assert_send(|| {
-        let guard = Bar { foo: Foo, x: 42 };
-        drop(guard.foo);
-        yield;
-    });
+    assert_send(
+        #[coroutine]
+        || {
+            let guard = Bar { foo: Foo, x: 42 };
+            drop(guard.foo);
+            yield;
+        },
+    );
 
-    assert_send(|| {
-        let mut guard = Bar { foo: Foo, x: 42 };
-        drop(guard);
-        guard = Bar { foo: Foo, x: 23 };
-        yield;
-    });
+    assert_send(
+        #[coroutine]
+        || {
+            let mut guard = Bar { foo: Foo, x: 42 };
+            drop(guard);
+            guard = Bar { foo: Foo, x: 23 };
+            yield;
+        },
+    );
 
-    assert_send(|| {
-        let guard = Bar { foo: Foo, x: 42 };
-        let Bar { foo, x } = guard;
-        drop(foo);
-        yield;
-    });
+    assert_send(
+        #[coroutine]
+        || {
+            let guard = Bar { foo: Foo, x: 42 };
+            let Bar { foo, x } = guard;
+            drop(foo);
+            yield;
+        },
+    );
 }
 
 fn assert_send<T: Send>(_: T) {}
diff --git a/tests/ui/coroutine/partial-initialization-across-yield.rs b/tests/ui/coroutine/partial-initialization-across-yield.rs
index 75ad5a22804..ab6f9c5b1e9 100644
--- a/tests/ui/coroutine/partial-initialization-across-yield.rs
+++ b/tests/ui/coroutine/partial-initialization-across-yield.rs
@@ -1,13 +1,13 @@
 // Test that we don't allow yielding from a coroutine while a local is partially
 // initialized.
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 struct S { x: i32, y: i32 }
 struct T(i32, i32);
 
 fn test_tuple() {
-    let _ = || {
+    let _ = #[coroutine] || {
         let mut t: (i32, i32);
         t.0 = 42; //~ ERROR E0381
         yield;
@@ -17,7 +17,7 @@ fn test_tuple() {
 }
 
 fn test_tuple_struct() {
-    let _ = || {
+    let _ = #[coroutine] || {
         let mut t: T;
         t.0 = 42; //~ ERROR E0381
         yield;
@@ -27,7 +27,7 @@ fn test_tuple_struct() {
 }
 
 fn test_struct() {
-    let _ = || {
+    let _ = #[coroutine] || {
         let mut t: S;
         t.x = 42; //~ ERROR E0381
         yield;
diff --git a/tests/ui/coroutine/pattern-borrow.rs b/tests/ui/coroutine/pattern-borrow.rs
index 76084433d47..46547504abc 100644
--- a/tests/ui/coroutine/pattern-borrow.rs
+++ b/tests/ui/coroutine/pattern-borrow.rs
@@ -5,7 +5,7 @@ enum Test { A(i32), B, }
 fn main() { }
 
 fn fun(test: Test) {
-    move || {
+    #[coroutine] move || {
         if let Test::A(ref _a) = test { //~ ERROR borrow may still be in use when coroutine yields
             yield ();
             _a.use_ref();
diff --git a/tests/ui/coroutine/pin-box-coroutine.rs b/tests/ui/coroutine/pin-box-coroutine.rs
index 1ee6393d1d8..d030f3ef214 100644
--- a/tests/ui/coroutine/pin-box-coroutine.rs
+++ b/tests/ui/coroutine/pin-box-coroutine.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 
@@ -8,6 +8,6 @@ fn assert_coroutine<G: Coroutine>(_: G) {
 }
 
 fn main() {
-    assert_coroutine(static || yield);
-    assert_coroutine(Box::pin(static || yield));
+    assert_coroutine(#[coroutine] static || yield);
+    assert_coroutine(Box::pin(#[coroutine] static || yield));
 }
diff --git a/tests/ui/coroutine/polymorphize-args.rs b/tests/ui/coroutine/polymorphize-args.rs
index 21aa3c7aafd..5123bf412b5 100644
--- a/tests/ui/coroutine/polymorphize-args.rs
+++ b/tests/ui/coroutine/polymorphize-args.rs
@@ -1,14 +1,15 @@
 //@ compile-flags: -Zpolymorphize=on
 //@ build-pass
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
 use std::thread;
 
 fn main() {
-    let mut foo = || yield;
+    let mut foo = #[coroutine]
+    || yield;
     thread::spawn(move || match Pin::new(&mut foo).resume(()) {
         s => panic!("bad state: {:?}", s),
     })
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-1.rs b/tests/ui/coroutine/print/coroutine-print-verbose-1.rs
index 73106328618..dc0165c9194 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-1.rs
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-1.rs
@@ -2,7 +2,7 @@
 
 // Same as: tests/ui/coroutine/issue-68112.stderr
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::{
     cell::RefCell,
@@ -30,7 +30,7 @@ fn make_non_send_coroutine() -> impl Coroutine<Return = Arc<RefCell<i32>>> {
 }
 
 fn test1() {
-    let send_gen = || {
+    let send_gen = #[coroutine] || {
         let _non_send_gen = make_non_send_coroutine();
         yield;
     };
@@ -39,7 +39,7 @@ fn test1() {
 }
 
 pub fn make_gen2<T>(t: T) -> impl Coroutine<Return = T> {
-    || {
+    #[coroutine] || {
         yield;
         t
     }
@@ -49,7 +49,7 @@ fn make_non_send_coroutine2() -> impl Coroutine<Return = Arc<RefCell<i32>>> {
 }
 
 fn test2() {
-    let send_gen = || {
+    let send_gen = #[coroutine] || {
         let _non_send_gen = make_non_send_coroutine2();
         yield;
     };
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr
index 37db83d57f7..934ab08cf17 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr
@@ -29,10 +29,10 @@ LL |     require_send(send_gen);
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this coroutine
-  --> $DIR/coroutine-print-verbose-1.rs:42:5
+  --> $DIR/coroutine-print-verbose-1.rs:42:18
    |
-LL |     || {
-   |     ^^
+LL |     #[coroutine] || {
+   |                  ^^
 note: required because it appears within the type `Opaque(DefId(0:35 ~ coroutine_print_verbose_1[75fb]::make_gen2::{opaque#0}), [Arc<RefCell<i32>>])`
   --> $DIR/coroutine-print-verbose-1.rs:41:30
    |
@@ -44,10 +44,10 @@ note: required because it appears within the type `Opaque(DefId(0:36 ~ coroutine
 LL | fn make_non_send_coroutine2() -> impl Coroutine<Return = Arc<RefCell<i32>>> {
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: required because it's used within this coroutine
-  --> $DIR/coroutine-print-verbose-1.rs:52:20
+  --> $DIR/coroutine-print-verbose-1.rs:52:33
    |
-LL |     let send_gen = || {
-   |                    ^^
+LL |     let send_gen = #[coroutine] || {
+   |                                 ^^
 note: required by a bound in `require_send`
   --> $DIR/coroutine-print-verbose-1.rs:26:25
    |
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-2.rs b/tests/ui/coroutine/print/coroutine-print-verbose-2.rs
index f9ea68a8cd9..ef7199cafdd 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-2.rs
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-2.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: -Zverbose-internals
 
 // Same as test/ui/coroutine/not-send-sync.rs
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 #![feature(negative_impls)]
 
 struct NotSend;
@@ -14,14 +14,14 @@ fn main() {
     fn assert_sync<T: Sync>(_: T) {}
     fn assert_send<T: Send>(_: T) {}
 
-    assert_sync(|| {
+    assert_sync(#[coroutine] || {
         //~^ ERROR: coroutine cannot be shared between threads safely
         let a = NotSync;
         yield;
         drop(a);
     });
 
-    assert_send(|| {
+    assert_send(#[coroutine] || {
         //~^ ERROR: coroutine cannot be sent between threads safely
         let a = NotSend;
         yield;
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr
index 26c9c27743c..0de53d9e1d7 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr
@@ -1,7 +1,7 @@
 error: coroutine cannot be shared between threads safely
   --> $DIR/coroutine-print-verbose-2.rs:17:5
    |
-LL | /     assert_sync(|| {
+LL | /     assert_sync(#[coroutine] || {
 LL | |
 LL | |         let a = NotSync;
 LL | |         yield;
@@ -26,7 +26,7 @@ LL |     fn assert_sync<T: Sync>(_: T) {}
 error: coroutine cannot be sent between threads safely
   --> $DIR/coroutine-print-verbose-2.rs:24:5
    |
-LL | /     assert_send(|| {
+LL | /     assert_send(#[coroutine] || {
 LL | |
 LL | |         let a = NotSend;
 LL | |         yield;
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-3.rs b/tests/ui/coroutine/print/coroutine-print-verbose-3.rs
index be6dbad9e1c..5dd15fc1b95 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-3.rs
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-3.rs
@@ -1,12 +1,13 @@
 //@ compile-flags: -Zverbose-internals
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 fn main() {
     let x = "Type mismatch test";
-    let coroutine :() = || {
-    //~^ ERROR mismatched types
+    let coroutine: () = #[coroutine]
+    || {
+        //~^ ERROR mismatched types
         yield 1i32;
-        return x
+        return x;
     };
 }
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr
index e2973cde6d3..dce45aeae56 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr
@@ -1,13 +1,12 @@
 error[E0308]: mismatched types
-  --> $DIR/coroutine-print-verbose-3.rs:7:25
+  --> $DIR/coroutine-print-verbose-3.rs:8:5
    |
-LL |       let coroutine :() = || {
-   |  ____________________--___^
-   | |                    |
-   | |                    expected due to this
+LL |       let coroutine: () = #[coroutine]
+   |                      -- expected due to this
+LL | /     || {
 LL | |
 LL | |         yield 1i32;
-LL | |         return x
+LL | |         return x;
 LL | |     };
    | |_____^ expected `()`, found coroutine
    |
diff --git a/tests/ui/coroutine/reborrow-mut-upvar.rs b/tests/ui/coroutine/reborrow-mut-upvar.rs
index e1f6211baeb..716781e365c 100644
--- a/tests/ui/coroutine/reborrow-mut-upvar.rs
+++ b/tests/ui/coroutine/reborrow-mut-upvar.rs
@@ -3,7 +3,7 @@
 #![feature(coroutines)]
 
 fn _run(bar: &mut i32) {
-    || { //~ WARN unused coroutine that must be used
+    #[coroutine] || { //~ WARN unused coroutine that must be used
         {
             let _baz = &*bar;
             yield;
diff --git a/tests/ui/coroutine/reborrow-mut-upvar.stderr b/tests/ui/coroutine/reborrow-mut-upvar.stderr
index 5b614ac4be8..a05e84c5f3e 100644
--- a/tests/ui/coroutine/reborrow-mut-upvar.stderr
+++ b/tests/ui/coroutine/reborrow-mut-upvar.stderr
@@ -1,7 +1,8 @@
 warning: unused coroutine that must be used
-  --> $DIR/reborrow-mut-upvar.rs:6:5
+  --> $DIR/reborrow-mut-upvar.rs:6:18
    |
-LL | /     || {
+LL |       #[coroutine] || {
+   |  __________________^
 LL | |         {
 LL | |             let _baz = &*bar;
 LL | |             yield;
diff --git a/tests/ui/coroutine/ref-escapes-but-not-over-yield.rs b/tests/ui/coroutine/ref-escapes-but-not-over-yield.rs
index a9c13188ff3..0f9c56786da 100644
--- a/tests/ui/coroutine/ref-escapes-but-not-over-yield.rs
+++ b/tests/ui/coroutine/ref-escapes-but-not-over-yield.rs
@@ -1,16 +1,17 @@
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn foo(x: &i32) {
     // In this case, a reference to `b` escapes the coroutine, but not
     // because of a yield. We see that there is no yield in the scope of
     // `b` and give the more generic error message.
     let mut a = &3;
-    let mut b = move || {
-        yield();
+    let mut b = #[coroutine]
+    move || {
+        yield ();
         let b = 5;
         a = &b;
         //~^ ERROR borrowed data escapes outside of coroutine
     };
 }
 
-fn main() { }
+fn main() {}
diff --git a/tests/ui/coroutine/ref-escapes-but-not-over-yield.stderr b/tests/ui/coroutine/ref-escapes-but-not-over-yield.stderr
index 8811faf2fad..6fa7082c0b8 100644
--- a/tests/ui/coroutine/ref-escapes-but-not-over-yield.stderr
+++ b/tests/ui/coroutine/ref-escapes-but-not-over-yield.stderr
@@ -1,5 +1,5 @@
 error[E0521]: borrowed data escapes outside of coroutine
-  --> $DIR/ref-escapes-but-not-over-yield.rs:11:9
+  --> $DIR/ref-escapes-but-not-over-yield.rs:12:9
    |
 LL |     let mut a = &3;
    |         ----- `a` declared here, outside of the coroutine body
diff --git a/tests/ui/coroutine/ref-upvar-not-send.rs b/tests/ui/coroutine/ref-upvar-not-send.rs
index 487fdeea2da..89bb5e5495f 100644
--- a/tests/ui/coroutine/ref-upvar-not-send.rs
+++ b/tests/ui/coroutine/ref-upvar-not-send.rs
@@ -1,7 +1,7 @@
 // For `Send` coroutines, suggest a `T: Sync` requirement for `&T` upvars,
 // and suggest a `T: Send` requirement for `&mut T` upvars.
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 fn assert_send<T: Send>(_: T) {}
 //~^ NOTE required by a bound in `assert_send`
@@ -12,7 +12,7 @@ fn assert_send<T: Send>(_: T) {}
 fn main() {
     let x: &*mut () = &std::ptr::null_mut();
     let y: &mut *mut () = &mut std::ptr::null_mut();
-    assert_send(move || {
+    assert_send(#[coroutine] move || {
         //~^ ERROR coroutine cannot be sent between threads safely
         //~| NOTE coroutine is not `Send`
         yield;
@@ -20,7 +20,7 @@ fn main() {
     });
     //~^^ NOTE captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
     //~| NOTE has type `&*mut ()` which is not `Send`, because `*mut ()` is not `Sync`
-    assert_send(move || {
+    assert_send(#[coroutine] move || {
         //~^ ERROR coroutine cannot be sent between threads safely
         //~| NOTE coroutine is not `Send`
         yield;
diff --git a/tests/ui/coroutine/ref-upvar-not-send.stderr b/tests/ui/coroutine/ref-upvar-not-send.stderr
index 0f91bcf4053..4c7deab3f4c 100644
--- a/tests/ui/coroutine/ref-upvar-not-send.stderr
+++ b/tests/ui/coroutine/ref-upvar-not-send.stderr
@@ -1,8 +1,8 @@
 error: coroutine cannot be sent between threads safely
-  --> $DIR/ref-upvar-not-send.rs:15:17
+  --> $DIR/ref-upvar-not-send.rs:15:30
    |
-LL |       assert_send(move || {
-   |  _________________^
+LL |       assert_send(#[coroutine] move || {
+   |  ______________________________^
 LL | |
 LL | |
 LL | |         yield;
@@ -10,7 +10,7 @@ LL | |         let _x = x;
 LL | |     });
    | |_____^ coroutine is not `Send`
    |
-   = help: the trait `Sync` is not implemented for `*mut ()`, which is required by `{coroutine@$DIR/ref-upvar-not-send.rs:15:17: 15:24}: Send`
+   = help: the trait `Sync` is not implemented for `*mut ()`, which is required by `{coroutine@$DIR/ref-upvar-not-send.rs:15:30: 15:37}: Send`
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
   --> $DIR/ref-upvar-not-send.rs:19:18
    |
@@ -23,10 +23,10 @@ LL | fn assert_send<T: Send>(_: T) {}
    |                   ^^^^ required by this bound in `assert_send`
 
 error: coroutine cannot be sent between threads safely
-  --> $DIR/ref-upvar-not-send.rs:23:17
+  --> $DIR/ref-upvar-not-send.rs:23:30
    |
-LL |       assert_send(move || {
-   |  _________________^
+LL |       assert_send(#[coroutine] move || {
+   |  ______________________________^
 LL | |
 LL | |
 LL | |         yield;
@@ -34,7 +34,7 @@ LL | |         let _y = y;
 LL | |     });
    | |_____^ coroutine is not `Send`
    |
-   = help: within `{coroutine@$DIR/ref-upvar-not-send.rs:23:17: 23:24}`, the trait `Send` is not implemented for `*mut ()`, which is required by `{coroutine@$DIR/ref-upvar-not-send.rs:23:17: 23:24}: Send`
+   = help: within `{coroutine@$DIR/ref-upvar-not-send.rs:23:30: 23:37}`, the trait `Send` is not implemented for `*mut ()`, which is required by `{coroutine@$DIR/ref-upvar-not-send.rs:23:30: 23:37}: Send`
 note: captured value is not `Send` because `&mut` references cannot be sent unless their referent is `Send`
   --> $DIR/ref-upvar-not-send.rs:27:18
    |
diff --git a/tests/ui/coroutine/reinit-in-match-guard.rs b/tests/ui/coroutine/reinit-in-match-guard.rs
index 4a584204773..0a97d9fbcb2 100644
--- a/tests/ui/coroutine/reinit-in-match-guard.rs
+++ b/tests/ui/coroutine/reinit-in-match-guard.rs
@@ -1,11 +1,11 @@
 //@ build-pass
 
-#![feature(coroutines)]
-
+#![feature(coroutines, stmt_expr_attributes)]
 #![allow(unused_assignments, dead_code)]
 
 fn main() {
-    let _ = || {
+    let _ = #[coroutine]
+    || {
         let mut x = vec![22_usize];
         std::mem::drop(x);
         match y() {
diff --git a/tests/ui/coroutine/resume-after-return.rs b/tests/ui/coroutine/resume-after-return.rs
index 81f86de641f..7028e1e81e5 100644
--- a/tests/ui/coroutine/resume-after-return.rs
+++ b/tests/ui/coroutine/resume-after-return.rs
@@ -1,17 +1,17 @@
 //@ run-pass
 //@ needs-unwind
 
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
-#![feature(coroutines, coroutine_trait)]
-
-use std::ops::{CoroutineState, Coroutine};
-use std::pin::Pin;
+use std::ops::{Coroutine, CoroutineState};
 use std::panic;
+use std::pin::Pin;
 
 fn main() {
-    let mut foo = || {
+    let mut foo = #[coroutine]
+    || {
         if true {
-            return
+            return;
         }
         yield;
     };
diff --git a/tests/ui/coroutine/resume-arg-late-bound.rs b/tests/ui/coroutine/resume-arg-late-bound.rs
index 3c2ab41047e..e84184da631 100644
--- a/tests/ui/coroutine/resume-arg-late-bound.rs
+++ b/tests/ui/coroutine/resume-arg-late-bound.rs
@@ -1,14 +1,14 @@
 //! Tests that we cannot produce a coroutine that accepts a resume argument
 //! with any lifetime and then stores it across a `yield`.
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 
 fn test(a: impl for<'a> Coroutine<&'a mut bool>) {}
 
 fn main() {
-    let gen = |arg: &mut bool| {
+    let gen = #[coroutine] |arg: &mut bool| {
         yield ();
         *arg = true;
     };
diff --git a/tests/ui/coroutine/resume-arg-late-bound.stderr b/tests/ui/coroutine/resume-arg-late-bound.stderr
index 4a4ee08c529..646abaf4f7b 100644
--- a/tests/ui/coroutine/resume-arg-late-bound.stderr
+++ b/tests/ui/coroutine/resume-arg-late-bound.stderr
@@ -4,7 +4,7 @@ error: implementation of `Coroutine` is not general enough
 LL |     test(gen);
    |     ^^^^^^^^^ implementation of `Coroutine` is not general enough
    |
-   = note: `{coroutine@$DIR/resume-arg-late-bound.rs:11:15: 11:31}` must implement `Coroutine<&'1 mut bool>`, for any lifetime `'1`...
+   = note: `{coroutine@$DIR/resume-arg-late-bound.rs:11:28: 11:44}` must implement `Coroutine<&'1 mut bool>`, for any lifetime `'1`...
    = note: ...but it actually implements `Coroutine<&'2 mut bool>`, for some specific lifetime `'2`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/coroutine/resume-arg-size.rs b/tests/ui/coroutine/resume-arg-size.rs
index 81e96975c98..59740a28f42 100644
--- a/tests/ui/coroutine/resume-arg-size.rs
+++ b/tests/ui/coroutine/resume-arg-size.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 #![allow(dropping_copy_types)]
 
 //@ run-pass
@@ -7,7 +7,8 @@ use std::mem::size_of_val;
 
 fn main() {
     // Coroutine taking a `Copy`able resume arg.
-    let gen_copy = |mut x: usize| {
+    let gen_copy = #[coroutine]
+    |mut x: usize| {
         loop {
             drop(x);
             x = yield;
@@ -15,7 +16,8 @@ fn main() {
     };
 
     // Coroutine taking a non-`Copy` resume arg.
-    let gen_move = |mut x: Box<usize>| {
+    let gen_move = #[coroutine]
+    |mut x: Box<usize>| {
         loop {
             drop(x);
             x = yield;
diff --git a/tests/ui/coroutine/resume-live-across-yield.rs b/tests/ui/coroutine/resume-live-across-yield.rs
index 45851411daa..b67619ee70f 100644
--- a/tests/ui/coroutine/resume-live-across-yield.rs
+++ b/tests/ui/coroutine/resume-live-across-yield.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::{Coroutine, CoroutineState};
 use std::pin::Pin;
@@ -18,7 +18,8 @@ impl Drop for Dropper {
 }
 
 fn main() {
-    let mut g = |mut _d| {
+    let mut g = #[coroutine]
+    |mut _d| {
         _d = yield;
         _d
     };
diff --git a/tests/ui/coroutine/retain-resume-ref.rs b/tests/ui/coroutine/retain-resume-ref.rs
index c9f995ab0cf..6e688c33979 100644
--- a/tests/ui/coroutine/retain-resume-ref.rs
+++ b/tests/ui/coroutine/retain-resume-ref.rs
@@ -1,6 +1,6 @@
 //! This test ensures that a mutable reference cannot be passed as a resume argument twice.
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::marker::Unpin;
 use std::ops::{
@@ -12,7 +12,8 @@ use std::pin::Pin;
 fn main() {
     let mut thing = String::from("hello");
 
-    let mut gen = |r| {
+    let mut gen = #[coroutine]
+    |r| {
         if false {
             yield r;
         }
diff --git a/tests/ui/coroutine/retain-resume-ref.stderr b/tests/ui/coroutine/retain-resume-ref.stderr
index eb8b78df6c9..e23023c6e23 100644
--- a/tests/ui/coroutine/retain-resume-ref.stderr
+++ b/tests/ui/coroutine/retain-resume-ref.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `thing` as mutable more than once at a time
-  --> $DIR/retain-resume-ref.rs:23:25
+  --> $DIR/retain-resume-ref.rs:24:25
    |
 LL |     gen.as_mut().resume(&mut thing);
    |                         ---------- first mutable borrow occurs here
diff --git a/tests/ui/coroutine/size-moved-locals.rs b/tests/ui/coroutine/size-moved-locals.rs
index eb5210087a0..0f800de8454 100644
--- a/tests/ui/coroutine/size-moved-locals.rs
+++ b/tests/ui/coroutine/size-moved-locals.rs
@@ -24,6 +24,7 @@ impl Drop for Foo {
 }
 
 fn move_before_yield() -> impl Coroutine<Yield = (), Return = ()> {
+    #[coroutine]
     static || {
         let first = Foo([0; FOO_SIZE]);
         let _second = first;
@@ -35,6 +36,7 @@ fn move_before_yield() -> impl Coroutine<Yield = (), Return = ()> {
 fn noop() {}
 
 fn move_before_yield_with_noop() -> impl Coroutine<Yield = (), Return = ()> {
+    #[coroutine]
     static || {
         let first = Foo([0; FOO_SIZE]);
         noop();
@@ -47,6 +49,7 @@ fn move_before_yield_with_noop() -> impl Coroutine<Yield = (), Return = ()> {
 // Today we don't have NRVO (we allocate space for both `first` and `second`,)
 // but we can overlap `first` with `_third`.
 fn overlap_move_points() -> impl Coroutine<Yield = (), Return = ()> {
+    #[coroutine]
     static || {
         let first = Foo([0; FOO_SIZE]);
         yield;
@@ -58,6 +61,7 @@ fn overlap_move_points() -> impl Coroutine<Yield = (), Return = ()> {
 }
 
 fn overlap_x_and_y() -> impl Coroutine<Yield = (), Return = ()> {
+    #[coroutine]
     static || {
         let x = Foo([0; FOO_SIZE]);
         yield;
diff --git a/tests/ui/coroutine/sized-yield.rs b/tests/ui/coroutine/sized-yield.rs
index 1368c88b522..a4c91fafe6c 100644
--- a/tests/ui/coroutine/sized-yield.rs
+++ b/tests/ui/coroutine/sized-yield.rs
@@ -1,11 +1,12 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 use std::pin::Pin;
 
 fn main() {
     let s = String::from("foo");
-    let mut gen = move || {
+    let mut gen = #[coroutine]
+    move || {
         //~^ ERROR the size for values of type
         yield s[..];
     };
diff --git a/tests/ui/coroutine/sized-yield.stderr b/tests/ui/coroutine/sized-yield.stderr
index 4e8dc13201d..5d5dd6803c8 100644
--- a/tests/ui/coroutine/sized-yield.stderr
+++ b/tests/ui/coroutine/sized-yield.stderr
@@ -1,8 +1,7 @@
 error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/sized-yield.rs:8:19
+  --> $DIR/sized-yield.rs:9:5
    |
-LL |       let mut gen = move || {
-   |  ___________________^
+LL | /     move || {
 LL | |
 LL | |         yield s[..];
 LL | |     };
@@ -12,7 +11,7 @@ LL | |     };
    = note: the yield type of a coroutine must have a statically known size
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/sized-yield.rs:12:24
+  --> $DIR/sized-yield.rs:13:24
    |
 LL |     Pin::new(&mut gen).resume(());
    |                        ^^^^^^ doesn't have a size known at compile-time
diff --git a/tests/ui/coroutine/smoke-resume-args.rs b/tests/ui/coroutine/smoke-resume-args.rs
index 7d20cd2293d..209c4814001 100644
--- a/tests/ui/coroutine/smoke-resume-args.rs
+++ b/tests/ui/coroutine/smoke-resume-args.rs
@@ -3,7 +3,7 @@
 //@ revisions: default nomiropt
 //@[nomiropt]compile-flags: -Z mir-opt-level=0
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::fmt::Debug;
 use std::ops::{
@@ -50,7 +50,7 @@ fn expect_drops<T>(expected_drops: usize, f: impl FnOnce() -> T) -> T {
 
 fn main() {
     drain(
-        &mut |mut b| {
+        &mut #[coroutine] |mut b| {
             while b != 0 {
                 b = yield (b + 1);
             }
@@ -59,21 +59,24 @@ fn main() {
         vec![(1, Yielded(2)), (-45, Yielded(-44)), (500, Yielded(501)), (0, Complete(-1))],
     );
 
-    expect_drops(2, || drain(&mut |a| yield a, vec![(DropMe, Yielded(DropMe))]));
+    expect_drops(2, || drain(&mut #[coroutine] |a| yield a, vec![(DropMe, Yielded(DropMe))]));
 
     expect_drops(6, || {
         drain(
-            &mut |a| yield yield a,
+            &mut #[coroutine] |a| yield yield a,
             vec![(DropMe, Yielded(DropMe)), (DropMe, Yielded(DropMe)), (DropMe, Complete(DropMe))],
         )
     });
 
     #[allow(unreachable_code)]
-    expect_drops(2, || drain(&mut |a| yield return a, vec![(DropMe, Complete(DropMe))]));
+    expect_drops(2, || drain(
+        &mut #[coroutine] |a| yield return a,
+        vec![(DropMe, Complete(DropMe))]
+    ));
 
     expect_drops(2, || {
         drain(
-            &mut |a: DropMe| {
+            &mut #[coroutine] |a: DropMe| {
                 if false { yield () } else { a }
             },
             vec![(DropMe, Complete(DropMe))],
@@ -83,7 +86,7 @@ fn main() {
     expect_drops(4, || {
         drain(
             #[allow(unused_assignments, unused_variables)]
-            &mut |mut a: DropMe| {
+            &mut #[coroutine] |mut a: DropMe| {
                 a = yield;
                 a = yield;
                 a = yield;
diff --git a/tests/ui/coroutine/smoke.rs b/tests/ui/coroutine/smoke.rs
index 17d98a52a1c..bfb183fde93 100644
--- a/tests/ui/coroutine/smoke.rs
+++ b/tests/ui/coroutine/smoke.rs
@@ -6,7 +6,7 @@
 //@ needs-threads
 //@ compile-flags: --test
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::{CoroutineState, Coroutine};
 use std::pin::Pin;
@@ -14,7 +14,7 @@ use std::thread;
 
 #[test]
 fn simple() {
-    let mut foo = || {
+    let mut foo = #[coroutine] || {
         if false {
             yield;
         }
@@ -29,7 +29,7 @@ fn simple() {
 #[test]
 fn return_capture() {
     let a = String::from("foo");
-    let mut foo = || {
+    let mut foo = #[coroutine] || {
         if false {
             yield;
         }
@@ -44,7 +44,7 @@ fn return_capture() {
 
 #[test]
 fn simple_yield() {
-    let mut foo = || {
+    let mut foo = #[coroutine] || {
         yield;
     };
 
@@ -61,7 +61,7 @@ fn simple_yield() {
 #[test]
 fn yield_capture() {
     let b = String::from("foo");
-    let mut foo = || {
+    let mut foo = #[coroutine] || {
         yield b;
     };
 
@@ -77,7 +77,7 @@ fn yield_capture() {
 
 #[test]
 fn simple_yield_value() {
-    let mut foo = || {
+    let mut foo = #[coroutine] || {
         yield String::from("bar");
         return String::from("foo")
     };
@@ -95,7 +95,7 @@ fn simple_yield_value() {
 #[test]
 fn return_after_yield() {
     let a = String::from("foo");
-    let mut foo = || {
+    let mut foo = #[coroutine] || {
         yield;
         return a
     };
@@ -112,34 +112,34 @@ fn return_after_yield() {
 
 #[test]
 fn send_and_sync() {
-    assert_send_sync(|| {
+    assert_send_sync(#[coroutine] || {
         yield
     });
-    assert_send_sync(|| {
+    assert_send_sync(#[coroutine] || {
         yield String::from("foo");
     });
-    assert_send_sync(|| {
+    assert_send_sync(#[coroutine] || {
         yield;
         return String::from("foo");
     });
     let a = 3;
-    assert_send_sync(|| {
+    assert_send_sync(#[coroutine] || {
         yield a;
         return
     });
     let a = 3;
-    assert_send_sync(move || {
+    assert_send_sync(#[coroutine] move || {
         yield a;
         return
     });
     let a = String::from("a");
-    assert_send_sync(|| {
+    assert_send_sync(#[coroutine] || {
         yield ;
         drop(a);
         return
     });
     let a = String::from("a");
-    assert_send_sync(move || {
+    assert_send_sync(#[coroutine] move || {
         yield ;
         drop(a);
         return
@@ -150,7 +150,7 @@ fn send_and_sync() {
 
 #[test]
 fn send_over_threads() {
-    let mut foo = || { yield };
+    let mut foo = #[coroutine] || { yield };
     thread::spawn(move || {
         match Pin::new(&mut foo).resume(()) {
             CoroutineState::Yielded(()) => {}
@@ -163,7 +163,7 @@ fn send_over_threads() {
     }).join().unwrap();
 
     let a = String::from("a");
-    let mut foo = || { yield a };
+    let mut foo = #[coroutine] || { yield a };
     thread::spawn(move || {
         match Pin::new(&mut foo).resume(()) {
             CoroutineState::Yielded(ref s) if *s == "a" => {}
diff --git a/tests/ui/coroutine/static-coroutine.rs b/tests/ui/coroutine/static-coroutine.rs
index 9beaef3e4de..eba6336d342 100644
--- a/tests/ui/coroutine/static-coroutine.rs
+++ b/tests/ui/coroutine/static-coroutine.rs
@@ -1,12 +1,13 @@
 //@ run-pass
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
-use std::pin::Pin;
 use std::ops::{Coroutine, CoroutineState};
+use std::pin::Pin;
 
 fn main() {
-    let mut coroutine = static || {
+    let mut coroutine = #[coroutine]
+    static || {
         let a = true;
         let b = &a;
         yield;
diff --git a/tests/ui/coroutine/static-mut-reference-across-yield.rs b/tests/ui/coroutine/static-mut-reference-across-yield.rs
index 0d8042ed852..40d5fdf2d57 100644
--- a/tests/ui/coroutine/static-mut-reference-across-yield.rs
+++ b/tests/ui/coroutine/static-mut-reference-across-yield.rs
@@ -1,6 +1,6 @@
 //@ build-pass
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 static mut A: [i32; 5] = [1, 2, 3, 4, 5];
 
@@ -8,13 +8,15 @@ fn is_send_sync<T: Send + Sync>(_: T) {}
 
 fn main() {
     unsafe {
-        let gen_index = static || {
+        let gen_index = #[coroutine]
+        static || {
             let u = A[{
                 yield;
                 1
             }];
         };
-        let gen_match = static || match A {
+        let gen_match = #[coroutine]
+        static || match A {
             i if {
                 yield;
                 true
diff --git a/tests/ui/coroutine/static-not-unpin.current.stderr b/tests/ui/coroutine/static-not-unpin.current.stderr
index 518abdd62c7..7d6260ac569 100644
--- a/tests/ui/coroutine/static-not-unpin.current.stderr
+++ b/tests/ui/coroutine/static-not-unpin.current.stderr
@@ -1,8 +1,8 @@
-error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:25: 15:34}` cannot be unpinned
+error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` cannot be unpinned
   --> $DIR/static-not-unpin.rs:18:18
    |
 LL |     assert_unpin(coroutine);
-   |     ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:25: 15:34}`
+   |     ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}`
    |     |
    |     required by a bound introduced by this call
    |
@@ -11,7 +11,7 @@ LL |     assert_unpin(coroutine);
 note: required by a bound in `assert_unpin`
   --> $DIR/static-not-unpin.rs:11:20
    |
-LL | fn assert_unpin<T: Unpin>(_: T) {
+LL | fn assert_unpin<T: Unpin>(_: T) {}
    |                    ^^^^^ required by this bound in `assert_unpin`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/coroutine/static-not-unpin.next.stderr b/tests/ui/coroutine/static-not-unpin.next.stderr
index 518abdd62c7..7d6260ac569 100644
--- a/tests/ui/coroutine/static-not-unpin.next.stderr
+++ b/tests/ui/coroutine/static-not-unpin.next.stderr
@@ -1,8 +1,8 @@
-error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:25: 15:34}` cannot be unpinned
+error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` cannot be unpinned
   --> $DIR/static-not-unpin.rs:18:18
    |
 LL |     assert_unpin(coroutine);
-   |     ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:25: 15:34}`
+   |     ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}`
    |     |
    |     required by a bound introduced by this call
    |
@@ -11,7 +11,7 @@ LL |     assert_unpin(coroutine);
 note: required by a bound in `assert_unpin`
   --> $DIR/static-not-unpin.rs:11:20
    |
-LL | fn assert_unpin<T: Unpin>(_: T) {
+LL | fn assert_unpin<T: Unpin>(_: T) {}
    |                    ^^^^^ required by this bound in `assert_unpin`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/coroutine/static-not-unpin.rs b/tests/ui/coroutine/static-not-unpin.rs
index 3704cca7729..2bc25e3796d 100644
--- a/tests/ui/coroutine/static-not-unpin.rs
+++ b/tests/ui/coroutine/static-not-unpin.rs
@@ -2,17 +2,17 @@
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
 
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 //@ normalize-stderr-test "std::pin::Unpin" -> "std::marker::Unpin"
 
 use std::marker::Unpin;
 
-fn assert_unpin<T: Unpin>(_: T) {
-}
+fn assert_unpin<T: Unpin>(_: T) {}
 
 fn main() {
-    let mut coroutine = static || {
+    let mut coroutine = #[coroutine]
+    static || {
         yield;
     };
     assert_unpin(coroutine); //~ ERROR E0277
diff --git a/tests/ui/coroutine/static-reference-across-yield.rs b/tests/ui/coroutine/static-reference-across-yield.rs
index cf19ccb54d5..e7ff658ebf6 100644
--- a/tests/ui/coroutine/static-reference-across-yield.rs
+++ b/tests/ui/coroutine/static-reference-across-yield.rs
@@ -4,10 +4,10 @@
 static A: [i32; 5] = [1, 2, 3, 4, 5];
 
 fn main() {
-    static || {
+    #[coroutine] static || {
         let u = A[{yield; 1}];
     };
-    static || {
+    #[coroutine] static || {
         match A {
             i if { yield; true } => (),
             _ => (),
diff --git a/tests/ui/coroutine/too-live-local-in-immovable-gen.rs b/tests/ui/coroutine/too-live-local-in-immovable-gen.rs
index 382e7ff3814..1c689ef7cef 100644
--- a/tests/ui/coroutine/too-live-local-in-immovable-gen.rs
+++ b/tests/ui/coroutine/too-live-local-in-immovable-gen.rs
@@ -5,7 +5,7 @@
 
 fn main() {
     unsafe {
-        static move || { //~ WARN unused coroutine that must be used
+        #[coroutine] static move || { //~ WARN unused coroutine that must be used
             // Tests that the coroutine transformation finds out that `a` is not live
             // during the yield expression. Type checking will also compute liveness
             // and it should also find out that `a` is not live.
diff --git a/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr b/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr
index 4a67dbe71e1..48df5c5beac 100644
--- a/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr
+++ b/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr
@@ -1,7 +1,8 @@
 warning: unused coroutine that must be used
-  --> $DIR/too-live-local-in-immovable-gen.rs:8:9
+  --> $DIR/too-live-local-in-immovable-gen.rs:8:22
    |
-LL | /         static move || {
+LL |           #[coroutine] static move || {
+   |  ______________________^
 LL | |             // Tests that the coroutine transformation finds out that `a` is not live
 LL | |             // during the yield expression. Type checking will also compute liveness
 LL | |             // and it should also find out that `a` is not live.
diff --git a/tests/ui/coroutine/too-many-parameters.rs b/tests/ui/coroutine/too-many-parameters.rs
index 377d80c7b22..3baaf062347 100644
--- a/tests/ui/coroutine/too-many-parameters.rs
+++ b/tests/ui/coroutine/too-many-parameters.rs
@@ -1,6 +1,7 @@
 #![feature(coroutines)]
 
 fn main() {
+    #[coroutine]
     |(), ()| {
         //~^ error: too many parameters for a coroutine
         yield;
diff --git a/tests/ui/coroutine/too-many-parameters.stderr b/tests/ui/coroutine/too-many-parameters.stderr
index c0917c7225b..45dad8e349e 100644
--- a/tests/ui/coroutine/too-many-parameters.stderr
+++ b/tests/ui/coroutine/too-many-parameters.stderr
@@ -1,5 +1,5 @@
 error[E0628]: too many parameters for a coroutine (expected 0 or 1 parameters)
-  --> $DIR/too-many-parameters.rs:4:5
+  --> $DIR/too-many-parameters.rs:5:5
    |
 LL |     |(), ()| {
    |     ^^^^^^^^
diff --git a/tests/ui/coroutine/type-mismatch-error.rs b/tests/ui/coroutine/type-mismatch-error.rs
index 0d04c21484c..ee4e27c20da 100644
--- a/tests/ui/coroutine/type-mismatch-error.rs
+++ b/tests/ui/coroutine/type-mismatch-error.rs
@@ -1,7 +1,7 @@
 //! Test that we get the expected type mismatch error instead of "closure is expected to take 0
 //! arguments" (which got introduced after implementing resume arguments).
 
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::Coroutine;
 
@@ -9,6 +9,7 @@ fn f<G: Coroutine>(_: G, _: G::Return) {}
 
 fn main() {
     f(
+        #[coroutine]
         |a: u8| {
             if false {
                 yield ();
diff --git a/tests/ui/coroutine/type-mismatch-error.stderr b/tests/ui/coroutine/type-mismatch-error.stderr
index 737d9afdd79..f10c30e2590 100644
--- a/tests/ui/coroutine/type-mismatch-error.stderr
+++ b/tests/ui/coroutine/type-mismatch-error.stderr
@@ -1,5 +1,5 @@
 error[E0308]: `if` and `else` have incompatible types
-  --> $DIR/type-mismatch-error.rs:16:17
+  --> $DIR/type-mismatch-error.rs:17:17
    |
 LL | /             if false {
 LL | |                 yield ();
diff --git a/tests/ui/coroutine/type-mismatch-signature-deduction.rs b/tests/ui/coroutine/type-mismatch-signature-deduction.rs
index d4ca622e80f..5b04b3efaaa 100644
--- a/tests/ui/coroutine/type-mismatch-signature-deduction.rs
+++ b/tests/ui/coroutine/type-mismatch-signature-deduction.rs
@@ -4,6 +4,7 @@ use std::ops::Coroutine;
 
 fn foo() -> impl Coroutine<Return = i32> {
     //~^ ERROR type mismatch
+    #[coroutine]
     || {
         if false {
             return Ok(6);
diff --git a/tests/ui/coroutine/type-mismatch-signature-deduction.stderr b/tests/ui/coroutine/type-mismatch-signature-deduction.stderr
index f26e30a8e74..08927196037 100644
--- a/tests/ui/coroutine/type-mismatch-signature-deduction.stderr
+++ b/tests/ui/coroutine/type-mismatch-signature-deduction.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/type-mismatch-signature-deduction.rs:14:9
+  --> $DIR/type-mismatch-signature-deduction.rs:15:9
    |
 LL |         5
    |         ^ expected `Result<{integer}, _>`, found integer
@@ -7,7 +7,7 @@ LL |         5
    = note: expected enum `Result<{integer}, _>`
               found type `{integer}`
 note: return type inferred to be `Result<{integer}, _>` here
-  --> $DIR/type-mismatch-signature-deduction.rs:9:20
+  --> $DIR/type-mismatch-signature-deduction.rs:10:20
    |
 LL |             return Ok(6);
    |                    ^^^^^
@@ -18,7 +18,7 @@ LL |         Ok(5)
 LL |         Err(5)
    |         ++++ +
 
-error[E0271]: type mismatch resolving `<{coroutine@$DIR/type-mismatch-signature-deduction.rs:7:5: 7:7} as Coroutine>::Return == i32`
+error[E0271]: type mismatch resolving `<{coroutine@$DIR/type-mismatch-signature-deduction.rs:8:5: 8:7} as Coroutine>::Return == i32`
   --> $DIR/type-mismatch-signature-deduction.rs:5:13
    |
 LL | fn foo() -> impl Coroutine<Return = i32> {
diff --git a/tests/ui/coroutine/uninhabited-field.rs b/tests/ui/coroutine/uninhabited-field.rs
index 79776d653b1..d6ada07ce0c 100644
--- a/tests/ui/coroutine/uninhabited-field.rs
+++ b/tests/ui/coroutine/uninhabited-field.rs
@@ -3,7 +3,7 @@
 #![allow(unused)]
 #![feature(assert_matches)]
 #![feature(coroutine_trait)]
-#![feature(coroutines)]
+#![feature(coroutines, stmt_expr_attributes)]
 #![feature(never_type)]
 use std::assert_matches::assert_matches;
 use std::ops::Coroutine;
@@ -13,7 +13,7 @@ use std::pin::Pin;
 fn conjure<T>() -> T { loop {} }
 
 fn run<T>(x: bool, y: bool) {
-    let mut c = || {
+    let mut c = #[coroutine] || {
         if x {
             let a : T;
             if y {
diff --git a/tests/ui/coroutine/unsized-capture-across-yield.rs b/tests/ui/coroutine/unsized-capture-across-yield.rs
index ef9cbc1d677..c86b1823aaf 100644
--- a/tests/ui/coroutine/unsized-capture-across-yield.rs
+++ b/tests/ui/coroutine/unsized-capture-across-yield.rs
@@ -7,6 +7,7 @@ use std::ops::Coroutine;
 
 fn capture() -> impl Coroutine {
     let b: [u8] = *(Box::new([]) as Box<[u8]>);
+    #[coroutine]
     move || {
         println!("{:?}", &b);
         //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
diff --git a/tests/ui/coroutine/unsized-capture-across-yield.stderr b/tests/ui/coroutine/unsized-capture-across-yield.stderr
index 436f0901a97..03551f1bbff 100644
--- a/tests/ui/coroutine/unsized-capture-across-yield.stderr
+++ b/tests/ui/coroutine/unsized-capture-across-yield.stderr
@@ -8,7 +8,7 @@ LL | #![feature(unsized_locals)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/unsized-capture-across-yield.rs:11:27
+  --> $DIR/unsized-capture-across-yield.rs:12:27
    |
 LL |     move || {
    |          -- this closure captures all values by move
diff --git a/tests/ui/coroutine/unsized-local-across-yield.rs b/tests/ui/coroutine/unsized-local-across-yield.rs
index 7a8ed60e46a..cb8ced13a11 100644
--- a/tests/ui/coroutine/unsized-local-across-yield.rs
+++ b/tests/ui/coroutine/unsized-local-across-yield.rs
@@ -6,6 +6,7 @@
 use std::ops::Coroutine;
 
 fn across() -> impl Coroutine {
+    #[coroutine]
     move || {
         let b: [u8] = *(Box::new([]) as Box<[u8]>);
         //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
diff --git a/tests/ui/coroutine/unsized-local-across-yield.stderr b/tests/ui/coroutine/unsized-local-across-yield.stderr
index c4c3be77ac2..4fe0f135a9d 100644
--- a/tests/ui/coroutine/unsized-local-across-yield.stderr
+++ b/tests/ui/coroutine/unsized-local-across-yield.stderr
@@ -8,7 +8,7 @@ LL | #![feature(unsized_locals)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/unsized-local-across-yield.rs:10:13
+  --> $DIR/unsized-local-across-yield.rs:11:13
    |
 LL |         let b: [u8] = *(Box::new([]) as Box<[u8]>);
    |             ^ doesn't have a size known at compile-time
diff --git a/tests/ui/coroutine/yield-in-args-rev.rs b/tests/ui/coroutine/yield-in-args-rev.rs
index b074e2bc939..29d79df25fb 100644
--- a/tests/ui/coroutine/yield-in-args-rev.rs
+++ b/tests/ui/coroutine/yield-in-args-rev.rs
@@ -10,7 +10,7 @@
 fn foo(_a: (), _b: &bool) {}
 
 fn bar() {
-    || { //~ WARN unused coroutine that must be used
+    #[coroutine] || { //~ WARN unused coroutine that must be used
         let b = true;
         foo(yield, &b);
     };
diff --git a/tests/ui/coroutine/yield-in-args-rev.stderr b/tests/ui/coroutine/yield-in-args-rev.stderr
index dbf46739e8b..10829d66185 100644
--- a/tests/ui/coroutine/yield-in-args-rev.stderr
+++ b/tests/ui/coroutine/yield-in-args-rev.stderr
@@ -1,7 +1,8 @@
 warning: unused coroutine that must be used
-  --> $DIR/yield-in-args-rev.rs:13:5
+  --> $DIR/yield-in-args-rev.rs:13:18
    |
-LL | /     || {
+LL |       #[coroutine] || {
+   |  __________________^
 LL | |         let b = true;
 LL | |         foo(yield, &b);
 LL | |     };
diff --git a/tests/ui/coroutine/yield-in-args.rs b/tests/ui/coroutine/yield-in-args.rs
index b2827148d77..bc9909b310c 100644
--- a/tests/ui/coroutine/yield-in-args.rs
+++ b/tests/ui/coroutine/yield-in-args.rs
@@ -3,6 +3,7 @@
 fn foo(_b: &bool, _a: ()) {}
 
 fn main() {
+    #[coroutine]
     || {
         let b = true;
         foo(&b, yield); //~ ERROR
diff --git a/tests/ui/coroutine/yield-in-args.stderr b/tests/ui/coroutine/yield-in-args.stderr
index 7233f47884b..1d2c54f9bdb 100644
--- a/tests/ui/coroutine/yield-in-args.stderr
+++ b/tests/ui/coroutine/yield-in-args.stderr
@@ -1,5 +1,5 @@
 error[E0626]: borrow may still be in use when coroutine yields
-  --> $DIR/yield-in-args.rs:8:13
+  --> $DIR/yield-in-args.rs:9:13
    |
 LL |         foo(&b, yield);
    |             ^^  ----- possible yield occurs here
diff --git a/tests/ui/coroutine/yield-in-const.rs b/tests/ui/coroutine/yield-in-const.rs
index 22651f32cf8..dc1b30155b9 100644
--- a/tests/ui/coroutine/yield-in-const.rs
+++ b/tests/ui/coroutine/yield-in-const.rs
@@ -2,5 +2,6 @@
 
 const A: u8 = { yield 3u8; 3u8};
 //~^ ERROR yield expression outside
+//~| ERROR `yield` can only be used in
 
 fn main() {}
diff --git a/tests/ui/coroutine/yield-in-const.stderr b/tests/ui/coroutine/yield-in-const.stderr
index d5748b05337..f02729412cc 100644
--- a/tests/ui/coroutine/yield-in-const.stderr
+++ b/tests/ui/coroutine/yield-in-const.stderr
@@ -1,9 +1,15 @@
+error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/yield-in-const.rs:3:17
+   |
+LL | const A: u8 = { yield 3u8; 3u8};
+   |                 ^^^^^^^^^
+
 error[E0627]: yield expression outside of coroutine literal
   --> $DIR/yield-in-const.rs:3:17
    |
 LL | const A: u8 = { yield 3u8; 3u8};
    |                 ^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0627`.
diff --git a/tests/ui/coroutine/yield-in-function.rs b/tests/ui/coroutine/yield-in-function.rs
index a99312043bd..427c5d0e7f5 100644
--- a/tests/ui/coroutine/yield-in-function.rs
+++ b/tests/ui/coroutine/yield-in-function.rs
@@ -2,3 +2,4 @@
 
 fn main() { yield; }
 //~^ ERROR yield expression outside
+//~| ERROR `yield` can only be used in
diff --git a/tests/ui/coroutine/yield-in-function.stderr b/tests/ui/coroutine/yield-in-function.stderr
index b9d4708bb8d..dbebf310b04 100644
--- a/tests/ui/coroutine/yield-in-function.stderr
+++ b/tests/ui/coroutine/yield-in-function.stderr
@@ -1,9 +1,20 @@
+error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/yield-in-function.rs:3:13
+   |
+LL | fn main() { yield; }
+   |             ^^^^^
+   |
+help: use `#[coroutine]` to make this closure a coroutine
+   |
+LL | #[coroutine] fn main() { yield; }
+   | ++++++++++++
+
 error[E0627]: yield expression outside of coroutine literal
   --> $DIR/yield-in-function.rs:3:13
    |
 LL | fn main() { yield; }
    |             ^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0627`.
diff --git a/tests/ui/coroutine/yield-in-initializer.rs b/tests/ui/coroutine/yield-in-initializer.rs
index 19218926b8a..3caefac013e 100644
--- a/tests/ui/coroutine/yield-in-initializer.rs
+++ b/tests/ui/coroutine/yield-in-initializer.rs
@@ -3,7 +3,7 @@
 #![feature(coroutines)]
 
 fn main() {
-    static || { //~ WARN unused coroutine that must be used
+    #[coroutine] static || { //~ WARN unused coroutine that must be used
         loop {
             // Test that `opt` is not live across the yield, even when borrowed in a loop
             // See https://github.com/rust-lang/rust/issues/52792
diff --git a/tests/ui/coroutine/yield-in-initializer.stderr b/tests/ui/coroutine/yield-in-initializer.stderr
index 614df43f2f5..1e22b787668 100644
--- a/tests/ui/coroutine/yield-in-initializer.stderr
+++ b/tests/ui/coroutine/yield-in-initializer.stderr
@@ -1,7 +1,8 @@
 warning: unused coroutine that must be used
-  --> $DIR/yield-in-initializer.rs:6:5
+  --> $DIR/yield-in-initializer.rs:6:18
    |
-LL | /     static || {
+LL |       #[coroutine] static || {
+   |  __________________^
 LL | |         loop {
 LL | |             // Test that `opt` is not live across the yield, even when borrowed in a loop
 LL | |             // See https://github.com/rust-lang/rust/issues/52792
diff --git a/tests/ui/coroutine/yield-in-static.rs b/tests/ui/coroutine/yield-in-static.rs
index 45e0380d46d..99d08913e64 100644
--- a/tests/ui/coroutine/yield-in-static.rs
+++ b/tests/ui/coroutine/yield-in-static.rs
@@ -2,5 +2,6 @@
 
 static B: u8 = { yield 3u8; 3u8};
 //~^ ERROR yield expression outside
+//~| ERROR `yield` can only be used in
 
 fn main() {}
diff --git a/tests/ui/coroutine/yield-in-static.stderr b/tests/ui/coroutine/yield-in-static.stderr
index b56283cab66..d1fd4eab0fc 100644
--- a/tests/ui/coroutine/yield-in-static.stderr
+++ b/tests/ui/coroutine/yield-in-static.stderr
@@ -1,9 +1,15 @@
+error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/yield-in-static.rs:3:18
+   |
+LL | static B: u8 = { yield 3u8; 3u8};
+   |                  ^^^^^^^^^
+
 error[E0627]: yield expression outside of coroutine literal
   --> $DIR/yield-in-static.rs:3:18
    |
 LL | static B: u8 = { yield 3u8; 3u8};
    |                  ^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0627`.
diff --git a/tests/ui/coroutine/yield-outside-coroutine-issue-78653.rs b/tests/ui/coroutine/yield-outside-coroutine-issue-78653.rs
index 31025c33b1a..6833bc99012 100644
--- a/tests/ui/coroutine/yield-outside-coroutine-issue-78653.rs
+++ b/tests/ui/coroutine/yield-outside-coroutine-issue-78653.rs
@@ -4,4 +4,5 @@ fn main() {
     yield || for i in 0 { }
     //~^ ERROR yield expression outside of coroutine literal
     //~| ERROR `{integer}` is not an iterator
+    //~| ERROR `yield` can only be used in
 }
diff --git a/tests/ui/coroutine/yield-outside-coroutine-issue-78653.stderr b/tests/ui/coroutine/yield-outside-coroutine-issue-78653.stderr
index 8f8bec99458..921e8d5d47a 100644
--- a/tests/ui/coroutine/yield-outside-coroutine-issue-78653.stderr
+++ b/tests/ui/coroutine/yield-outside-coroutine-issue-78653.stderr
@@ -1,3 +1,14 @@
+error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/yield-outside-coroutine-issue-78653.rs:4:5
+   |
+LL |     yield || for i in 0 { }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `#[coroutine]` to make this closure a coroutine
+   |
+LL | #[coroutine] fn main() {
+   | ++++++++++++
+
 error[E0627]: yield expression outside of coroutine literal
   --> $DIR/yield-outside-coroutine-issue-78653.rs:4:5
    |
@@ -14,7 +25,7 @@ LL |     yield || for i in 0 { }
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
    = note: required for `{integer}` to implement `IntoIterator`
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0627.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/coroutine/yield-subtype.rs b/tests/ui/coroutine/yield-subtype.rs
index 271f8362f17..adee5075e83 100644
--- a/tests/ui/coroutine/yield-subtype.rs
+++ b/tests/ui/coroutine/yield-subtype.rs
@@ -8,7 +8,7 @@ fn bar<'a>() {
     let a: &'static str = "hi";
     let b: &'a str = a;
 
-    || { //~ WARN unused coroutine that must be used
+    #[coroutine] || { //~ WARN unused coroutine that must be used
         yield a;
         yield b;
     };
diff --git a/tests/ui/coroutine/yield-subtype.stderr b/tests/ui/coroutine/yield-subtype.stderr
index 5e7ae9f581e..973415327a5 100644
--- a/tests/ui/coroutine/yield-subtype.stderr
+++ b/tests/ui/coroutine/yield-subtype.stderr
@@ -1,7 +1,8 @@
 warning: unused coroutine that must be used
-  --> $DIR/yield-subtype.rs:11:5
+  --> $DIR/yield-subtype.rs:11:18
    |
-LL | /     || {
+LL |       #[coroutine] || {
+   |  __________________^
 LL | |         yield a;
 LL | |         yield b;
 LL | |     };
diff --git a/tests/ui/coroutine/yield-while-iterating.rs b/tests/ui/coroutine/yield-while-iterating.rs
index 66ac6d3922a..77f601e4f2c 100644
--- a/tests/ui/coroutine/yield-while-iterating.rs
+++ b/tests/ui/coroutine/yield-while-iterating.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::ops::{CoroutineState, Coroutine};
 use std::cell::Cell;
@@ -9,7 +9,7 @@ fn yield_during_iter_owned_data(x: Vec<i32>) {
     // reference to it.  This winds up becoming a rather confusing
     // regionck error -- in particular, we would freeze with the
     // reference in scope, and it doesn't live long enough.
-    let _b = move || {
+    let _b =#[coroutine]  move || {
         for p in &x { //~ ERROR
             yield();
         }
@@ -17,7 +17,7 @@ fn yield_during_iter_owned_data(x: Vec<i32>) {
 }
 
 fn yield_during_iter_borrowed_slice(x: &[i32]) {
-    let _b = move || {
+    let _b = #[coroutine] move || {
         for p in x {
             yield();
         }
@@ -26,7 +26,7 @@ fn yield_during_iter_borrowed_slice(x: &[i32]) {
 
 fn yield_during_iter_borrowed_slice_2() {
     let mut x = vec![22_i32];
-    let _b = || {
+    let _b = #[coroutine] || {
         for p in &x {
             yield();
         }
@@ -38,7 +38,7 @@ fn yield_during_iter_borrowed_slice_3() {
     // OK to take a mutable ref to `x` and yield
     // up pointers from it:
     let mut x = vec![22_i32];
-    let mut b = || {
+    let mut b = #[coroutine] || {
         for p in &mut x {
             yield p;
         }
@@ -50,7 +50,7 @@ fn yield_during_iter_borrowed_slice_4() {
     // ...but not OK to do that while reading
     // from `x` too
     let mut x = vec![22_i32];
-    let mut b = || {
+    let mut b = #[coroutine] || {
         for p in &mut x {
             yield p;
         }
@@ -61,7 +61,7 @@ fn yield_during_iter_borrowed_slice_4() {
 
 fn yield_during_range_iter() {
     // Should be OK.
-    let mut b = || {
+    let mut b = #[coroutine] || {
         let v = vec![1,2,3];
         let len = v.len();
         for i in 0..len {
diff --git a/tests/ui/coroutine/yield-while-iterating.stderr b/tests/ui/coroutine/yield-while-iterating.stderr
index 5330121f372..f81c914c4bd 100644
--- a/tests/ui/coroutine/yield-while-iterating.stderr
+++ b/tests/ui/coroutine/yield-while-iterating.stderr
@@ -9,8 +9,8 @@ LL |             yield();
 error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
   --> $DIR/yield-while-iterating.rs:58:20
    |
-LL |     let mut b = || {
-   |                 -- mutable borrow occurs here
+LL |     let mut b = #[coroutine] || {
+   |                              -- mutable borrow occurs here
 LL |         for p in &mut x {
    |                       - first borrow occurs due to use of `x` in coroutine
 ...
diff --git a/tests/ui/coroutine/yield-while-local-borrowed.rs b/tests/ui/coroutine/yield-while-local-borrowed.rs
index 7f8d1d4543d..3db30c36712 100644
--- a/tests/ui/coroutine/yield-while-local-borrowed.rs
+++ b/tests/ui/coroutine/yield-while-local-borrowed.rs
@@ -1,4 +1,4 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 use std::cell::Cell;
 use std::ops::{Coroutine, CoroutineState};
@@ -9,7 +9,7 @@ fn borrow_local_inline() {
     //
     // (This error occurs because the region shows up in the type of
     // `b` and gets extended by region inference.)
-    let mut b = move || {
+    let mut b = #[coroutine] move || {
         let a = &mut 3;
         //~^ ERROR borrow may still be in use when coroutine yields
         yield ();
@@ -20,7 +20,7 @@ fn borrow_local_inline() {
 
 fn borrow_local_inline_done() {
     // No error here -- `a` is not in scope at the point of `yield`.
-    let mut b = move || {
+    let mut b = #[coroutine] move || {
         {
             let a = &mut 3;
         }
@@ -34,7 +34,7 @@ fn borrow_local() {
     //
     // (This error occurs because the region shows up in the type of
     // `b` and gets extended by region inference.)
-    let mut b = move || {
+    let mut b = #[coroutine] move || {
         let a = 3;
         {
             let b = &a;
diff --git a/tests/ui/coroutine/yield-while-ref-reborrowed.rs b/tests/ui/coroutine/yield-while-ref-reborrowed.rs
index 07c59175858..2600d0b4124 100644
--- a/tests/ui/coroutine/yield-while-ref-reborrowed.rs
+++ b/tests/ui/coroutine/yield-while-ref-reborrowed.rs
@@ -1,15 +1,16 @@
-#![feature(coroutines, coroutine_trait)]
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
-use std::ops::{CoroutineState, Coroutine};
 use std::cell::Cell;
+use std::ops::{Coroutine, CoroutineState};
 use std::pin::Pin;
 
 fn reborrow_shared_ref(x: &i32) {
     // This is OK -- we have a borrow live over the yield, but it's of
     // data that outlives the coroutine.
-    let mut b = move || {
+    let mut b = #[coroutine]
+    move || {
         let a = &*x;
-        yield();
+        yield ();
         println!("{}", a);
     };
     Pin::new(&mut b).resume(());
@@ -18,9 +19,10 @@ fn reborrow_shared_ref(x: &i32) {
 fn reborrow_mutable_ref(x: &mut i32) {
     // This is OK -- we have a borrow live over the yield, but it's of
     // data that outlives the coroutine.
-    let mut b = move || {
+    let mut b = #[coroutine]
+    move || {
         let a = &mut *x;
-        yield();
+        yield ();
         println!("{}", a);
     };
     Pin::new(&mut b).resume(());
@@ -28,13 +30,14 @@ fn reborrow_mutable_ref(x: &mut i32) {
 
 fn reborrow_mutable_ref_2(x: &mut i32) {
     // ...but not OK to go on using `x`.
-    let mut b = || {
+    let mut b = #[coroutine]
+    || {
         let a = &mut *x;
-        yield();
+        yield ();
         println!("{}", a);
     };
     println!("{}", x); //~ ERROR
     Pin::new(&mut b).resume(());
 }
 
-fn main() { }
+fn main() {}
diff --git a/tests/ui/coroutine/yield-while-ref-reborrowed.stderr b/tests/ui/coroutine/yield-while-ref-reborrowed.stderr
index 62ac0265311..7c9b766457d 100644
--- a/tests/ui/coroutine/yield-while-ref-reborrowed.stderr
+++ b/tests/ui/coroutine/yield-while-ref-reborrowed.stderr
@@ -1,8 +1,8 @@
 error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access
-  --> $DIR/yield-while-ref-reborrowed.rs:36:20
+  --> $DIR/yield-while-ref-reborrowed.rs:39:20
    |
-LL |     let mut b = || {
-   |                 -- coroutine construction occurs here
+LL |     || {
+   |     -- coroutine construction occurs here
 LL |         let a = &mut *x;
    |                      -- first borrow occurs due to use of `x` in coroutine
 ...