about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/language-features/coroutines.md246
-rw-r--r--src/doc/unstable-book/src/language-features/generators.md246
-rw-r--r--src/tools/clippy/clippy_lints/src/async_yields_async.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_question_mark.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_async_block.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_async.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-5238.rs2
-rw-r--r--src/tools/clippy/tests/ui/large_futures.fixed2
-rw-r--r--src/tools/clippy/tests/ui/large_futures.rs2
-rw-r--r--src/tools/miri/src/helpers.rs2
-rw-r--r--src/tools/miri/tests/fail/generator-pinned-moved.rs14
-rw-r--r--src/tools/miri/tests/fail/generator-pinned-moved.stderr10
-rw-r--r--src/tools/miri/tests/pass/coroutine.rs (renamed from src/tools/miri/tests/pass/generator.rs)10
-rw-r--r--src/tools/miri/tests/pass/move-data-across-await-point.rs2
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/generators-self-referential.rs6
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs2
-rw-r--r--src/tools/miri/tests/pass/track-caller-attribute.rs28
-rw-r--r--src/tools/miri/tests/pass/tree_borrows/tree-borrows.rs2
-rw-r--r--src/tools/rustfmt/tests/source/immovable_generators.rs2
-rw-r--r--src/tools/rustfmt/tests/target/immovable_generators.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue_4110.rs2
27 files changed, 307 insertions, 307 deletions
diff --git a/src/doc/unstable-book/src/language-features/coroutines.md b/src/doc/unstable-book/src/language-features/coroutines.md
new file mode 100644
index 00000000000..fb1ba791aef
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/coroutines.md
@@ -0,0 +1,246 @@
+# `coroutines`
+
+The tracking issue for this feature is: [#43122]
+
+[#43122]: https://github.com/rust-lang/rust/issues/43122
+
+------------------------
+
+The `coroutines` feature gate in Rust allows you to define coroutine or
+coroutine literals. A coroutine is a "resumable function" that syntactically
+resembles a closure but compiles to much different semantics in the compiler
+itself. The primary feature of a coroutine is that it can be suspended during
+execution to be resumed at a later date. Coroutines use the `yield` keyword to
+"return", and then the caller can `resume` a coroutine to resume execution just
+after the `yield` keyword.
+
+Coroutines are an extra-unstable feature in the compiler right now. Added in
+[RFC 2033] they're mostly intended right now as a information/constraint
+gathering phase. The intent is that experimentation can happen on the nightly
+compiler before actual stabilization. A further RFC will be required to
+stabilize coroutines/coroutines and will likely contain at least a few small
+tweaks to the overall design.
+
+[RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
+
+A syntactical example of a coroutine is:
+
+```rust
+#![feature(coroutines, coroutine_trait)]
+
+use std::ops::{Coroutine, CoroutineState};
+use std::pin::Pin;
+
+fn main() {
+    let mut coroutine = || {
+        yield 1;
+        return "foo"
+    };
+
+    match Pin::new(&mut coroutine).resume(()) {
+        CoroutineState::Yielded(1) => {}
+        _ => panic!("unexpected value from resume"),
+    }
+    match Pin::new(&mut coroutine).resume(()) {
+        CoroutineState::Complete("foo") => {}
+        _ => panic!("unexpected value from resume"),
+    }
+}
+```
+
+Coroutines are closure-like literals which can contain a `yield` statement. The
+`yield` statement takes an optional expression of a value to yield out of the
+coroutine. All coroutine literals implement the `Coroutine` trait in the
+`std::ops` module. The `Coroutine` trait has one main method, `resume`, which
+resumes execution of the coroutine at the previous suspension point.
+
+An example of the control flow of coroutines is that the following example
+prints all numbers in order:
+
+```rust
+#![feature(coroutines, coroutine_trait)]
+
+use std::ops::Coroutine;
+use std::pin::Pin;
+
+fn main() {
+    let mut coroutine = || {
+        println!("2");
+        yield;
+        println!("4");
+    };
+
+    println!("1");
+    Pin::new(&mut coroutine).resume(());
+    println!("3");
+    Pin::new(&mut coroutine).resume(());
+    println!("5");
+}
+```
+
+At this time the main intended use case of coroutines is an implementation
+primitive for async/await syntax, but coroutines will likely be extended to
+ergonomic implementations of iterators and other primitives in the future.
+Feedback on the design and usage is always appreciated!
+
+### The `Coroutine` trait
+
+The `Coroutine` trait in `std::ops` currently looks like:
+
+```rust
+# #![feature(arbitrary_self_types, coroutine_trait)]
+# use std::ops::CoroutineState;
+# use std::pin::Pin;
+
+pub trait Coroutine<R = ()> {
+    type Yield;
+    type Return;
+    fn resume(self: Pin<&mut Self>, resume: R) -> CoroutineState<Self::Yield, Self::Return>;
+}
+```
+
+The `Coroutine::Yield` type is the type of values that can be yielded with the
+`yield` statement. The `Coroutine::Return` type is the returned type of the
+coroutine. This is typically the last expression in a coroutine's definition or
+any value passed to `return` in a coroutine. The `resume` function is the entry
+point for executing the `Coroutine` itself.
+
+The return value of `resume`, `CoroutineState`, looks like:
+
+```rust
+pub enum CoroutineState<Y, R> {
+    Yielded(Y),
+    Complete(R),
+}
+```
+
+The `Yielded` variant indicates that the coroutine can later be resumed. This
+corresponds to a `yield` point in a coroutine. The `Complete` variant indicates
+that the coroutine is complete and cannot be resumed again. Calling `resume`
+after a coroutine has returned `Complete` will likely result in a panic of the
+program.
+
+### Closure-like semantics
+
+The closure-like syntax for coroutines alludes to the fact that they also have
+closure-like semantics. Namely:
+
+* When created, a coroutine executes no code. A closure literal does not
+  actually execute any of the closure's code on construction, and similarly a
+  coroutine literal does not execute any code inside the coroutine when
+  constructed.
+
+* Coroutines can capture outer variables by reference or by move, and this can
+  be tweaked with the `move` keyword at the beginning of the closure. Like
+  closures all coroutines will have an implicit environment which is inferred by
+  the compiler. Outer variables can be moved into a coroutine for use as the
+  coroutine progresses.
+
+* Coroutine literals produce a value with a unique type which implements the
+  `std::ops::Coroutine` trait. This allows actual execution of the coroutine
+  through the `Coroutine::resume` method as well as also naming it in return
+  types and such.
+
+* Traits like `Send` and `Sync` are automatically implemented for a `Coroutine`
+  depending on the captured variables of the environment. Unlike closures,
+  coroutines also depend on variables live across suspension points. This means
+  that although the ambient environment may be `Send` or `Sync`, the coroutine
+  itself may not be due to internal variables live across `yield` points being
+  not-`Send` or not-`Sync`. Note that coroutines do
+  not implement traits like `Copy` or `Clone` automatically.
+
+* Whenever a coroutine is dropped it will drop all captured environment
+  variables.
+
+### Coroutines as state machines
+
+In the compiler, coroutines are currently compiled as state machines. Each
+`yield` expression will correspond to a different state that stores all live
+variables over that suspension point. Resumption of a coroutine will dispatch on
+the current state and then execute internally until a `yield` is reached, at
+which point all state is saved off in the coroutine and a value is returned.
+
+Let's take a look at an example to see what's going on here:
+
+```rust
+#![feature(coroutines, coroutine_trait)]
+
+use std::ops::Coroutine;
+use std::pin::Pin;
+
+fn main() {
+    let ret = "foo";
+    let mut coroutine = move || {
+        yield 1;
+        return ret
+    };
+
+    Pin::new(&mut coroutine).resume(());
+    Pin::new(&mut coroutine).resume(());
+}
+```
+
+This coroutine literal will compile down to something similar to:
+
+```rust
+#![feature(arbitrary_self_types, coroutines, coroutine_trait)]
+
+use std::ops::{Coroutine, CoroutineState};
+use std::pin::Pin;
+
+fn main() {
+    let ret = "foo";
+    let mut coroutine = {
+        enum __Coroutine {
+            Start(&'static str),
+            Yield1(&'static str),
+            Done,
+        }
+
+        impl Coroutine for __Coroutine {
+            type Yield = i32;
+            type Return = &'static str;
+
+            fn resume(mut self: Pin<&mut Self>, resume: ()) -> CoroutineState<i32, &'static str> {
+                use std::mem;
+                match mem::replace(&mut *self, __Coroutine::Done) {
+                    __Coroutine::Start(s) => {
+                        *self = __Coroutine::Yield1(s);
+                        CoroutineState::Yielded(1)
+                    }
+
+                    __Coroutine::Yield1(s) => {
+                        *self = __Coroutine::Done;
+                        CoroutineState::Complete(s)
+                    }
+
+                    __Coroutine::Done => {
+                        panic!("coroutine resumed after completion")
+                    }
+                }
+            }
+        }
+
+        __Coroutine::Start(ret)
+    };
+
+    Pin::new(&mut coroutine).resume(());
+    Pin::new(&mut coroutine).resume(());
+}
+```
+
+Notably here we can see that the compiler is generating a fresh type,
+`__Coroutine` in this case. This type has a number of states (represented here
+as an `enum`) corresponding to each of the conceptual states of the coroutine.
+At the beginning we're closing over our outer variable `foo` and then that
+variable is also live over the `yield` point, so it's stored in both states.
+
+When the coroutine starts it'll immediately yield 1, but it saves off its state
+just before it does so indicating that it has reached the yield point. Upon
+resuming again we'll execute the `return ret` which returns the `Complete`
+state.
+
+Here we can also note that the `Done` state, if resumed, panics immediately as
+it's invalid to resume a completed coroutine. It's also worth noting that this
+is just a rough desugaring, not a normative specification for what the compiler
+does.
diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md
deleted file mode 100644
index 7b865c9c679..00000000000
--- a/src/doc/unstable-book/src/language-features/generators.md
+++ /dev/null
@@ -1,246 +0,0 @@
-# `generators`
-
-The tracking issue for this feature is: [#43122]
-
-[#43122]: https://github.com/rust-lang/rust/issues/43122
-
-------------------------
-
-The `generators` feature gate in Rust allows you to define generator or
-coroutine literals. A generator is a "resumable function" that syntactically
-resembles a closure but compiles to much different semantics in the compiler
-itself. The primary feature of a generator is that it can be suspended during
-execution to be resumed at a later date. Generators use the `yield` keyword to
-"return", and then the caller can `resume` a generator to resume execution just
-after the `yield` keyword.
-
-Generators are an extra-unstable feature in the compiler right now. Added in
-[RFC 2033] they're mostly intended right now as a information/constraint
-gathering phase. The intent is that experimentation can happen on the nightly
-compiler before actual stabilization. A further RFC will be required to
-stabilize generators/coroutines and will likely contain at least a few small
-tweaks to the overall design.
-
-[RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
-
-A syntactical example of a generator is:
-
-```rust
-#![feature(generators, generator_trait)]
-
-use std::ops::{Generator, GeneratorState};
-use std::pin::Pin;
-
-fn main() {
-    let mut generator = || {
-        yield 1;
-        return "foo"
-    };
-
-    match Pin::new(&mut generator).resume(()) {
-        GeneratorState::Yielded(1) => {}
-        _ => panic!("unexpected value from resume"),
-    }
-    match Pin::new(&mut generator).resume(()) {
-        GeneratorState::Complete("foo") => {}
-        _ => panic!("unexpected value from resume"),
-    }
-}
-```
-
-Generators are closure-like literals which can contain a `yield` statement. The
-`yield` statement takes an optional expression of a value to yield out of the
-generator. All generator literals implement the `Generator` trait in the
-`std::ops` module. The `Generator` trait has one main method, `resume`, which
-resumes execution of the generator at the previous suspension point.
-
-An example of the control flow of generators is that the following example
-prints all numbers in order:
-
-```rust
-#![feature(generators, generator_trait)]
-
-use std::ops::Generator;
-use std::pin::Pin;
-
-fn main() {
-    let mut generator = || {
-        println!("2");
-        yield;
-        println!("4");
-    };
-
-    println!("1");
-    Pin::new(&mut generator).resume(());
-    println!("3");
-    Pin::new(&mut generator).resume(());
-    println!("5");
-}
-```
-
-At this time the main intended use case of generators is an implementation
-primitive for async/await syntax, but generators will likely be extended to
-ergonomic implementations of iterators and other primitives in the future.
-Feedback on the design and usage is always appreciated!
-
-### The `Generator` trait
-
-The `Generator` trait in `std::ops` currently looks like:
-
-```rust
-# #![feature(arbitrary_self_types, generator_trait)]
-# use std::ops::GeneratorState;
-# use std::pin::Pin;
-
-pub trait Generator<R = ()> {
-    type Yield;
-    type Return;
-    fn resume(self: Pin<&mut Self>, resume: R) -> GeneratorState<Self::Yield, Self::Return>;
-}
-```
-
-The `Generator::Yield` type is the type of values that can be yielded with the
-`yield` statement. The `Generator::Return` type is the returned type of the
-generator. This is typically the last expression in a generator's definition or
-any value passed to `return` in a generator. The `resume` function is the entry
-point for executing the `Generator` itself.
-
-The return value of `resume`, `GeneratorState`, looks like:
-
-```rust
-pub enum GeneratorState<Y, R> {
-    Yielded(Y),
-    Complete(R),
-}
-```
-
-The `Yielded` variant indicates that the generator can later be resumed. This
-corresponds to a `yield` point in a generator. The `Complete` variant indicates
-that the generator is complete and cannot be resumed again. Calling `resume`
-after a generator has returned `Complete` will likely result in a panic of the
-program.
-
-### Closure-like semantics
-
-The closure-like syntax for generators alludes to the fact that they also have
-closure-like semantics. Namely:
-
-* When created, a generator executes no code. A closure literal does not
-  actually execute any of the closure's code on construction, and similarly a
-  generator literal does not execute any code inside the generator when
-  constructed.
-
-* Generators can capture outer variables by reference or by move, and this can
-  be tweaked with the `move` keyword at the beginning of the closure. Like
-  closures all generators will have an implicit environment which is inferred by
-  the compiler. Outer variables can be moved into a generator for use as the
-  generator progresses.
-
-* Generator literals produce a value with a unique type which implements the
-  `std::ops::Generator` trait. This allows actual execution of the generator
-  through the `Generator::resume` method as well as also naming it in return
-  types and such.
-
-* Traits like `Send` and `Sync` are automatically implemented for a `Generator`
-  depending on the captured variables of the environment. Unlike closures,
-  generators also depend on variables live across suspension points. This means
-  that although the ambient environment may be `Send` or `Sync`, the generator
-  itself may not be due to internal variables live across `yield` points being
-  not-`Send` or not-`Sync`. Note that generators do
-  not implement traits like `Copy` or `Clone` automatically.
-
-* Whenever a generator is dropped it will drop all captured environment
-  variables.
-
-### Generators as state machines
-
-In the compiler, generators are currently compiled as state machines. Each
-`yield` expression will correspond to a different state that stores all live
-variables over that suspension point. Resumption of a generator will dispatch on
-the current state and then execute internally until a `yield` is reached, at
-which point all state is saved off in the generator and a value is returned.
-
-Let's take a look at an example to see what's going on here:
-
-```rust
-#![feature(generators, generator_trait)]
-
-use std::ops::Generator;
-use std::pin::Pin;
-
-fn main() {
-    let ret = "foo";
-    let mut generator = move || {
-        yield 1;
-        return ret
-    };
-
-    Pin::new(&mut generator).resume(());
-    Pin::new(&mut generator).resume(());
-}
-```
-
-This generator literal will compile down to something similar to:
-
-```rust
-#![feature(arbitrary_self_types, generators, generator_trait)]
-
-use std::ops::{Generator, GeneratorState};
-use std::pin::Pin;
-
-fn main() {
-    let ret = "foo";
-    let mut generator = {
-        enum __Generator {
-            Start(&'static str),
-            Yield1(&'static str),
-            Done,
-        }
-
-        impl Generator for __Generator {
-            type Yield = i32;
-            type Return = &'static str;
-
-            fn resume(mut self: Pin<&mut Self>, resume: ()) -> GeneratorState<i32, &'static str> {
-                use std::mem;
-                match mem::replace(&mut *self, __Generator::Done) {
-                    __Generator::Start(s) => {
-                        *self = __Generator::Yield1(s);
-                        GeneratorState::Yielded(1)
-                    }
-
-                    __Generator::Yield1(s) => {
-                        *self = __Generator::Done;
-                        GeneratorState::Complete(s)
-                    }
-
-                    __Generator::Done => {
-                        panic!("generator resumed after completion")
-                    }
-                }
-            }
-        }
-
-        __Generator::Start(ret)
-    };
-
-    Pin::new(&mut generator).resume(());
-    Pin::new(&mut generator).resume(());
-}
-```
-
-Notably here we can see that the compiler is generating a fresh type,
-`__Generator` in this case. This type has a number of states (represented here
-as an `enum`) corresponding to each of the conceptual states of the generator.
-At the beginning we're closing over our outer variable `foo` and then that
-variable is also live over the `yield` point, so it's stored in both states.
-
-When the generator starts it'll immediately yield 1, but it saves off its state
-just before it does so indicating that it has reached the yield point. Upon
-resuming again we'll execute the `return ret` which returns the `Complete`
-state.
-
-Here we can also note that the `Done` state, if resumed, panics immediately as
-it's invalid to resume a completed generator. It's also worth noting that this
-is just a rough desugaring, not a normative specification for what the compiler
-does.
diff --git a/src/tools/clippy/clippy_lints/src/async_yields_async.rs b/src/tools/clippy/clippy_lints/src/async_yields_async.rs
index 99daec560e7..96a90d599ab 100644
--- a/src/tools/clippy/clippy_lints/src/async_yields_async.rs
+++ b/src/tools/clippy/clippy_lints/src/async_yields_async.rs
@@ -48,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
         use AsyncCoroutineKind::{Block, Closure};
         // For functions, with explicitly defined types, don't warn.
         // XXXkhuey maybe we should?
-        if let Some(CoroutineKind::Async(Block | Closure)) = body.generator_kind {
+        if let Some(CoroutineKind::Async(Block | Closure)) = body.coroutine_kind {
             if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() {
                 let body_id = BodyId {
                     hir_id: body.value.hir_id,
diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
index 65d131c5751..60f9bbd7458 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -196,25 +196,25 @@ impl LateLintPass<'_> for AwaitHolding {
 
     fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {
         use AsyncCoroutineKind::{Block, Closure, Fn};
-        if let Some(CoroutineKind::Async(Block | Closure | Fn)) = body.generator_kind {
+        if let Some(CoroutineKind::Async(Block | Closure | Fn)) = body.coroutine_kind {
             let def_id = cx.tcx.hir().body_owner_def_id(body.id());
-            if let Some(generator_layout) = cx.tcx.mir_generator_witnesses(def_id) {
-                self.check_interior_types(cx, generator_layout);
+            if let Some(coroutine_layout) = cx.tcx.mir_coroutine_witnesses(def_id) {
+                self.check_interior_types(cx, coroutine_layout);
             }
         }
     }
 }
 
 impl AwaitHolding {
-    fn check_interior_types(&self, cx: &LateContext<'_>, generator: &CoroutineLayout<'_>) {
-        for (ty_index, ty_cause) in generator.field_tys.iter_enumerated() {
+    fn check_interior_types(&self, cx: &LateContext<'_>, coroutine: &CoroutineLayout<'_>) {
+        for (ty_index, ty_cause) in coroutine.field_tys.iter_enumerated() {
             if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind() {
                 let await_points = || {
-                    generator
+                    coroutine
                         .variant_source_info
                         .iter_enumerated()
                         .filter_map(|(variant, source_info)| {
-                            generator.variant_fields[variant]
+                            coroutine.variant_fields[variant]
                                 .raw
                                 .contains(&ty_index)
                                 .then_some(source_info.span)
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index ca9defc2bf3..fc9b381664a 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -437,7 +437,7 @@ fn lint_for_missing_headers(
                 let ret_ty = typeck.expr_ty(body.value);
                 if implements_trait(cx, ret_ty, future, &[]);
                 if let ty::Coroutine(_, subs, _) = ret_ty.kind();
-                if is_type_diagnostic_item(cx, subs.as_generator().return_ty(), sym::Result);
+                if is_type_diagnostic_item(cx, subs.as_coroutine().return_ty(), sym::Result);
                 then {
                     span_lint(
                         cx,
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index 49976334751..914ceca2995 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -188,7 +188,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>)
             ..
         } = block_expr;
         let closure_body = cx.tcx.hir().body(body);
-        if closure_body.generator_kind == Some(CoroutineKind::Async(AsyncCoroutineKind::Block));
+        if closure_body.coroutine_kind == Some(CoroutineKind::Async(AsyncCoroutineKind::Block));
         then {
             return Some(closure_body);
         }
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
index 674d3451748..b44a2716dde 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
@@ -26,7 +26,7 @@ pub(super) fn check<'tcx>(
     if_chain! {
         if !expr.span.from_expansion();
         if let ExprKind::Closure(c) = m_arg.kind;
-        if let Body {params: [p], value: body_expr, generator_kind: _ } = cx.tcx.hir().body(c.body);
+        if let Body {params: [p], value: body_expr, coroutine_kind: _ } = cx.tcx.hir().body(c.body);
         if let PatKind::Tuple([key_pat, val_pat], _) = p.pat.kind;
 
         let (replacement_kind, annotation, bound_ident) = match (&key_pat.kind, &val_pat.kind) {
diff --git a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
index f2c823323bb..d267b3de7f2 100644
--- a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
@@ -87,7 +87,7 @@ impl LateLintPass<'_> for NeedlessQuestionMark {
     }
 
     fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {
-        if let Some(CoroutineKind::Async(AsyncCoroutineKind::Fn)) = body.generator_kind {
+        if let Some(CoroutineKind::Async(AsyncCoroutineKind::Fn)) = body.coroutine_kind {
             if let ExprKind::Block(
                 Block {
                     expr:
diff --git a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
index 59aecd23278..b8f787e1f1f 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
@@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock {
 fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
     if let ExprKind::Closure(Closure { body, def_id, .. }) = expr.kind &&
         let body = cx.tcx.hir().body(*body) &&
-        matches!(body.generator_kind, Some(CoroutineKind::Async(AsyncCoroutineKind::Block)))
+        matches!(body.coroutine_kind, Some(CoroutineKind::Async(AsyncCoroutineKind::Block)))
     {
         cx
             .typeck_results()
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index f42836611ca..c18237e887d 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -144,7 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
             // without this check, we'd end up linting twice.
             && !matches!(recv.kind, hir::ExprKind::Call(..))
             && let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)
-            && let Some((body, fn_decl, generator_kind)) = find_innermost_closure(cx, recv, call_depth)
+            && let Some((body, fn_decl, coroutine_kind)) = find_innermost_closure(cx, recv, call_depth)
         {
             span_lint_and_then(
                 cx,
@@ -156,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                         let mut applicability = Applicability::MachineApplicable;
                         let mut hint = Sugg::hir_with_context(cx, body, full_expr.span.ctxt(), "..", &mut applicability);
 
-                        if generator_kind.is_async()
+                        if coroutine_kind.is_async()
                             && let hir::ExprKind::Closure(closure) = body.kind
                         {
                             let async_closure_body = cx.tcx.hir().body(closure.body);
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index 5e1ba1b0dc0..3649f8792ae 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -86,7 +86,7 @@ impl<'a, 'tcx> Visitor<'tcx> for AsyncFnVisitor<'a, 'tcx> {
     }
 
     fn visit_body(&mut self, b: &'tcx Body<'tcx>) {
-        let is_async_block = matches!(b.generator_kind, Some(rustc_hir::CoroutineKind::Async(_)));
+        let is_async_block = matches!(b.coroutine_kind, Some(rustc_hir::CoroutineKind::Async(_)));
 
         if is_async_block {
             self.async_depth += 1;
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 0d8fd9d2adf..f6096ea546d 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -306,7 +306,7 @@ fn check_terminator<'tcx>(
         },
         TerminatorKind::SwitchInt { discr, targets: _ } => check_operand(tcx, discr, span, body),
         TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } => {
-            Err((span, "const fn generators are unstable".into()))
+            Err((span, "const fn coroutines are unstable".into()))
         },
         TerminatorKind::Call {
             func,
diff --git a/src/tools/clippy/tests/ui/crashes/ice-5238.rs b/src/tools/clippy/tests/ui/crashes/ice-5238.rs
index 989eb6d4485..b1fc3fb9d25 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-5238.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-5238.rs
@@ -1,6 +1,6 @@
 // Regression test for #5238 / https://github.com/rust-lang/rust/pull/69562
 
-#![feature(generators, generator_trait)]
+#![feature(coroutines, coroutine_trait)]
 
 fn main() {
     let _ = || {
diff --git a/src/tools/clippy/tests/ui/large_futures.fixed b/src/tools/clippy/tests/ui/large_futures.fixed
index 4c192d1c8d1..aa8c3021b97 100644
--- a/src/tools/clippy/tests/ui/large_futures.fixed
+++ b/src/tools/clippy/tests/ui/large_futures.fixed
@@ -1,4 +1,4 @@
-#![feature(generators)]
+#![feature(coroutines)]
 #![warn(clippy::large_futures)]
 #![allow(clippy::never_loop)]
 #![allow(clippy::future_not_send)]
diff --git a/src/tools/clippy/tests/ui/large_futures.rs b/src/tools/clippy/tests/ui/large_futures.rs
index 557d89a9cf9..fc6ea458d3d 100644
--- a/src/tools/clippy/tests/ui/large_futures.rs
+++ b/src/tools/clippy/tests/ui/large_futures.rs
@@ -1,4 +1,4 @@
-#![feature(generators)]
+#![feature(coroutines)]
 #![warn(clippy::large_futures)]
 #![allow(clippy::never_loop)]
 #![allow(clippy::future_not_send)]
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 0dc472bc486..690c6619aba 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -492,7 +492,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     // `Variants::Multiple`.
                     match v.layout.variants {
                         Variants::Multiple { .. } => {
-                            // A multi-variant enum, or generator, or so.
+                            // A multi-variant enum, or coroutine, or so.
                             // Treat this like a union: without reading from memory,
                             // we cannot determine the variant we are in. Reading from
                             // memory would be subject to Stacked Borrows rules, leading
diff --git a/src/tools/miri/tests/fail/generator-pinned-moved.rs b/src/tools/miri/tests/fail/generator-pinned-moved.rs
index 5a1dbc8a0ed..005ae7e9132 100644
--- a/src/tools/miri/tests/fail/generator-pinned-moved.rs
+++ b/src/tools/miri/tests/fail/generator-pinned-moved.rs
@@ -1,5 +1,5 @@
 //@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
-#![feature(generators, generator_trait)]
+#![feature(coroutines, coroutine_trait)]
 
 use std::{
     ops::{Coroutine, CoroutineState},
@@ -35,12 +35,12 @@ where
 }
 
 fn main() {
-    let mut generator_iterator_2 = {
-        let mut generator_iterator = Box::new(CoroutineIteratorAdapter(firstn()));
-        generator_iterator.next(); // pin it
+    let mut coroutine_iterator_2 = {
+        let mut coroutine_iterator = Box::new(CoroutineIteratorAdapter(firstn()));
+        coroutine_iterator.next(); // pin it
 
-        Box::new(*generator_iterator) // move it
-    }; // *deallocate* generator_iterator
+        Box::new(*coroutine_iterator) // move it
+    }; // *deallocate* coroutine_iterator
 
-    generator_iterator_2.next(); // and use moved value
+    coroutine_iterator_2.next(); // and use moved value
 }
diff --git a/src/tools/miri/tests/fail/generator-pinned-moved.stderr b/src/tools/miri/tests/fail/generator-pinned-moved.stderr
index 7465ec2bc83..547b63f7e2c 100644
--- a/src/tools/miri/tests/fail/generator-pinned-moved.stderr
+++ b/src/tools/miri/tests/fail/generator-pinned-moved.stderr
@@ -9,25 +9,25 @@ LL |         *num += 1;
 help: ALLOC was allocated here:
   --> $DIR/generator-pinned-moved.rs:LL:CC
    |
-LL |         let mut generator_iterator = Box::new(CoroutineIteratorAdapter(firstn()));
+LL |         let mut coroutine_iterator = Box::new(CoroutineIteratorAdapter(firstn()));
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: ALLOC was deallocated here:
   --> $DIR/generator-pinned-moved.rs:LL:CC
    |
-LL |     }; // *deallocate* generator_iterator
+LL |     }; // *deallocate* coroutine_iterator
    |     ^
    = note: BACKTRACE (of the first span):
    = note: inside closure at $DIR/generator-pinned-moved.rs:LL:CC
-note: inside `<CoroutineIteratorAdapter<{static generator@$DIR/generator-pinned-moved.rs:LL:CC}> as std::iter::Iterator>::next`
+note: inside `<CoroutineIteratorAdapter<{static coroutine@$DIR/generator-pinned-moved.rs:LL:CC}> as std::iter::Iterator>::next`
   --> $DIR/generator-pinned-moved.rs:LL:CC
    |
 LL |         match me.resume(()) {
    |               ^^^^^^^^^^^^^
-   = note: inside `<std::boxed::Box<CoroutineIteratorAdapter<{static generator@$DIR/generator-pinned-moved.rs:LL:CC}>> as std::iter::Iterator>::next` at RUSTLIB/alloc/src/boxed.rs:LL:CC
+   = note: inside `<std::boxed::Box<CoroutineIteratorAdapter<{static coroutine@$DIR/generator-pinned-moved.rs:LL:CC}>> as std::iter::Iterator>::next` at RUSTLIB/alloc/src/boxed.rs:LL:CC
 note: inside `main`
   --> $DIR/generator-pinned-moved.rs:LL:CC
    |
-LL |     generator_iterator_2.next(); // and use moved value
+LL |     coroutine_iterator_2.next(); // and use moved value
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/pass/generator.rs b/src/tools/miri/tests/pass/coroutine.rs
index a1d3e9462bf..49bfa92a052 100644
--- a/src/tools/miri/tests/pass/generator.rs
+++ b/src/tools/miri/tests/pass/coroutine.rs
@@ -1,6 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
-#![feature(generators, generator_trait, never_type)]
+#![feature(coroutines, coroutine_trait, never_type)]
 
 use std::fmt::Debug;
 use std::mem::ManuallyDrop;
@@ -21,8 +21,8 @@ fn basic() {
         let mut t = unsafe { Pin::new_unchecked(&mut t) };
         loop {
             let state = t.as_mut().resume(());
-            // Test if the generator is valid (according to type invariants).
-            // For self-referential generators however this is UB!
+            // Test if the coroutine is valid (according to type invariants).
+            // For self-referential coroutines however this is UB!
             if !self_referential {
                 let _ = unsafe { ManuallyDrop::new(ptr::read(t.as_mut().get_unchecked_mut())) };
             }
@@ -86,7 +86,7 @@ fn basic() {
         yield 1;
     });
 
-    // also test self-referential generators
+    // also test self-referential coroutines
     assert_eq!(
         finish(5, true, static || {
             let mut x = 5;
@@ -145,7 +145,7 @@ fn smoke_resume_arg() {
 
         for (input, out) in inout {
             assert_eq!(gen.as_mut().resume(input), out);
-            // Test if the generator is valid (according to type invariants).
+            // Test if the coroutine is valid (according to type invariants).
             let _ = unsafe { ManuallyDrop::new(ptr::read(gen.as_mut().get_unchecked_mut())) };
         }
     }
diff --git a/src/tools/miri/tests/pass/move-data-across-await-point.rs b/src/tools/miri/tests/pass/move-data-across-await-point.rs
index 489fae66ffb..5990d66fbdd 100644
--- a/src/tools/miri/tests/pass/move-data-across-await-point.rs
+++ b/src/tools/miri/tests/pass/move-data-across-await-point.rs
@@ -15,7 +15,7 @@ async fn data_moved_async() {
         // `raw_pointer` points to the original location where the Vec was stored in the caller.
         // `data` is where that Vec (to be precise, its ptr+capacity+len on-stack data)
         // got moved to. Those will usually not be the same since the Vec got moved twice
-        // (into the function call, and then into the generator upvar).
+        // (into the function call, and then into the coroutine upvar).
         assert_ne!(raw_pointer, raw_pointer2);
         unsafe {
             // This writes into the `x` in `data_moved_async`, re-initializing it.
diff --git a/src/tools/miri/tests/pass/stacked-borrows/generators-self-referential.rs b/src/tools/miri/tests/pass/stacked-borrows/generators-self-referential.rs
index d727cf6e886..c4b15c8758b 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/generators-self-referential.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/generators-self-referential.rs
@@ -1,6 +1,6 @@
 // See https://github.com/rust-lang/unsafe-code-guidelines/issues/148:
 // this fails when Stacked Borrows is strictly applied even to `!Unpin` types.
-#![feature(generators, generator_trait)]
+#![feature(coroutines, coroutine_trait)]
 
 use std::{
     ops::{Coroutine, CoroutineState},
@@ -24,8 +24,8 @@ fn firstn() -> impl Coroutine<Yield = u64, Return = ()> {
 }
 
 fn main() {
-    let mut generator_iterator = firstn();
-    let mut pin = unsafe { Pin::new_unchecked(&mut generator_iterator) };
+    let mut coroutine_iterator = firstn();
+    let mut pin = unsafe { Pin::new_unchecked(&mut coroutine_iterator) };
     let mut sum = 0;
     while let CoroutineState::Yielded(x) = pin.as_mut().resume(()) {
         sum += x;
diff --git a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs
index d2ba1841844..dd3ee36f988 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs
@@ -223,7 +223,7 @@ fn wide_raw_ptr_in_tuple() {
 fn not_unpin_not_protected() {
     // `&mut !Unpin`, at least for now, does not get `noalias` nor `dereferenceable`, so we also
     // don't add protectors. (We could, but until we have a better idea for where we want to go with
-    // the self-referential-generator situation, it does not seem worth the potential trouble.)
+    // the self-referential-coroutine situation, it does not seem worth the potential trouble.)
     use std::marker::PhantomPinned;
 
     pub struct NotUnpin(i32, PhantomPinned);
diff --git a/src/tools/miri/tests/pass/track-caller-attribute.rs b/src/tools/miri/tests/pass/track-caller-attribute.rs
index bf59617d80f..d88bcc98858 100644
--- a/src/tools/miri/tests/pass/track-caller-attribute.rs
+++ b/src/tools/miri/tests/pass/track-caller-attribute.rs
@@ -1,8 +1,8 @@
 #![feature(core_intrinsics)]
 #![feature(stmt_expr_attributes)]
 #![feature(closure_track_caller)]
-#![feature(generator_trait)]
-#![feature(generators)]
+#![feature(coroutine_trait)]
+#![feature(coroutines)]
 
 use std::ops::{Coroutine, CoroutineState};
 use std::panic::Location;
@@ -210,9 +210,9 @@ fn test_closure() {
     assert_eq!(non_tracked_loc.column(), 33);
 }
 
-fn test_generator() {
+fn test_coroutine() {
     #[track_caller]
-    fn mono_generator<F: Coroutine<String, Yield = (&'static str, String, Loc), Return = ()>>(
+    fn mono_coroutine<F: Coroutine<String, Yield = (&'static str, String, Loc), Return = ()>>(
         val: Pin<&mut F>,
     ) -> (&'static str, String, Loc) {
         match val.resume("Mono".to_string()) {
@@ -222,7 +222,7 @@ fn test_generator() {
     }
 
     #[track_caller]
-    fn dyn_generator(
+    fn dyn_coroutine(
         val: Pin<&mut dyn Coroutine<String, Yield = (&'static str, String, Loc), Return = ()>>,
     ) -> (&'static str, String, Loc) {
         match val.resume("Dyn".to_string()) {
@@ -232,32 +232,32 @@ fn test_generator() {
     }
 
     #[rustfmt::skip]
-    let generator = #[track_caller] |arg: String| {
+    let coroutine = #[track_caller] |arg: String| {
         yield ("first", arg.clone(), Location::caller());
         yield ("second", arg.clone(), Location::caller());
     };
 
-    let mut pinned = Box::pin(generator);
-    let (dyn_ret, dyn_arg, dyn_loc) = dyn_generator(pinned.as_mut());
+    let mut pinned = Box::pin(coroutine);
+    let (dyn_ret, dyn_arg, dyn_loc) = dyn_coroutine(pinned.as_mut());
     assert_eq!(dyn_ret, "first");
     assert_eq!(dyn_arg, "Dyn".to_string());
     // The `Coroutine` trait does not have `#[track_caller]` on `resume`, so
     // this will not match.
     assert_ne!(dyn_loc.file(), file!());
 
-    let (mono_ret, mono_arg, mono_loc) = mono_generator(pinned.as_mut());
+    let (mono_ret, mono_arg, mono_loc) = mono_coroutine(pinned.as_mut());
     let mono_line = line!() - 1;
     assert_eq!(mono_ret, "second");
-    // The generator ignores the argument to the second `resume` call
+    // The coroutine ignores the argument to the second `resume` call
     assert_eq!(mono_arg, "Dyn".to_string());
     assert_eq!(mono_loc.file(), file!());
     assert_eq!(mono_loc.line(), mono_line);
     assert_eq!(mono_loc.column(), 42);
 
     #[rustfmt::skip]
-    let non_tracked_generator = || { yield Location::caller(); };
-    let non_tracked_line = line!() - 1; // This is the line of the generator, not its caller
-    let non_tracked_loc = match Box::pin(non_tracked_generator).as_mut().resume(()) {
+    let non_tracked_coroutine = || { yield Location::caller(); };
+    let non_tracked_line = line!() - 1; // This is the line of the coroutine, not its caller
+    let non_tracked_loc = match Box::pin(non_tracked_coroutine).as_mut().resume(()) {
         CoroutineState::Yielded(val) => val,
         _ => unreachable!(),
     };
@@ -272,5 +272,5 @@ fn main() {
     test_trait_obj();
     test_trait_obj2();
     test_closure();
-    test_generator();
+    test_coroutine();
 }
diff --git a/src/tools/miri/tests/pass/tree_borrows/tree-borrows.rs b/src/tools/miri/tests/pass/tree_borrows/tree-borrows.rs
index 89752bffe9f..d45be91afcc 100644
--- a/src/tools/miri/tests/pass/tree_borrows/tree-borrows.rs
+++ b/src/tools/miri/tests/pass/tree_borrows/tree-borrows.rs
@@ -315,7 +315,7 @@ fn wide_raw_ptr_in_tuple() {
 fn not_unpin_not_protected() {
     // `&mut !Unpin`, at least for now, does not get `noalias` nor `dereferenceable`, so we also
     // don't add protectors. (We could, but until we have a better idea for where we want to go with
-    // the self-referential-generator situation, it does not seem worth the potential trouble.)
+    // the self-referential-coroutine situation, it does not seem worth the potential trouble.)
     use std::marker::PhantomPinned;
 
     pub struct NotUnpin(i32, PhantomPinned);
diff --git a/src/tools/rustfmt/tests/source/immovable_generators.rs b/src/tools/rustfmt/tests/source/immovable_generators.rs
index c57a1e14483..3b94af0c96c 100644
--- a/src/tools/rustfmt/tests/source/immovable_generators.rs
+++ b/src/tools/rustfmt/tests/source/immovable_generators.rs
@@ -1,4 +1,4 @@
-#![feature(generators)]
+#![feature(coroutines)]
 
 unsafe fn foo() {
     let mut ga = static || { 
diff --git a/src/tools/rustfmt/tests/target/immovable_generators.rs b/src/tools/rustfmt/tests/target/immovable_generators.rs
index 0bf7a2d91ba..f52cfa00f97 100644
--- a/src/tools/rustfmt/tests/target/immovable_generators.rs
+++ b/src/tools/rustfmt/tests/target/immovable_generators.rs
@@ -1,4 +1,4 @@
-#![feature(generators)]
+#![feature(coroutines)]
 
 unsafe fn foo() {
     let mut ga = static || {
diff --git a/src/tools/rustfmt/tests/target/issue_4110.rs b/src/tools/rustfmt/tests/target/issue_4110.rs
index d3734e90b7f..ea8fa3b73d2 100644
--- a/src/tools/rustfmt/tests/target/issue_4110.rs
+++ b/src/tools/rustfmt/tests/target/issue_4110.rs
@@ -12,7 +12,7 @@ fn bindings() {
                 span,
                 ..
             },
-        ) if borrow_spans.for_generator() | borrow_spans.for_closure() => self
+        ) if borrow_spans.for_coroutine() | borrow_spans.for_closure() => self
             .report_escaping_closure_capture(
                 borrow_spans,
                 borrow_span,