about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs28
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs18
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs26
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs13
-rw-r--r--compiler/rustc_hir/src/hir.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs20
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs3
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs8
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/ty/util.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs9
-rw-r--r--compiler/rustc_passes/src/loops.rs11
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs4
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs4
-rw-r--r--compiler/stable_mir/src/mir/body.rs6
25 files changed, 130 insertions, 104 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 04483b8e150..e62a442b884 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -691,7 +691,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             body,
             fn_decl_span: self.lower_span(span),
             fn_arg_span: None,
-            kind: hir::ClosureKind::Coroutine(coroutine_kind, Movability::Static),
+            kind: hir::ClosureKind::Coroutine(coroutine_kind),
             constness: hir::Constness::NotConst,
         }))
     }
@@ -744,7 +744,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             body,
             fn_decl_span: self.lower_span(span),
             fn_arg_span: None,
-            kind: hir::ClosureKind::Coroutine(coroutine_kind, Movability::Movable),
+            kind: hir::ClosureKind::Coroutine(coroutine_kind),
             constness: hir::Constness::NotConst,
         }))
     }
@@ -829,7 +829,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             body,
             fn_decl_span: self.lower_span(span),
             fn_arg_span: None,
-            kind: hir::ClosureKind::Coroutine(coroutine_kind, Movability::Static),
+            kind: hir::ClosureKind::Coroutine(coroutine_kind),
             constness: hir::Constness::NotConst,
         }))
     }
@@ -898,7 +898,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let is_async_gen = match self.coroutine_kind {
             Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => false,
             Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
-            Some(hir::CoroutineKind::Coroutine)
+            Some(hir::CoroutineKind::Coroutine(_))
             | Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
             | None => {
                 return hir::ExprKind::Err(self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
@@ -1126,11 +1126,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         movability: Movability,
     ) -> hir::ClosureKind {
         match coroutine_kind {
-            Some(hir::CoroutineKind::Coroutine) => {
+            Some(hir::CoroutineKind::Coroutine(_)) => {
                 if decl.inputs.len() > 1 {
                     self.tcx.sess.emit_err(CoroutineTooManyParameters { fn_decl_span });
                 }
-                hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine, movability)
+                hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(movability))
             }
             Some(
                 hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)
@@ -1655,7 +1655,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span }),
                 );
             }
-            Some(hir::CoroutineKind::Coroutine) | None => {
+            Some(hir::CoroutineKind::Coroutine(_)) => {
                 if !self.tcx.features().coroutines {
                     rustc_session::parse::feature_err(
                         &self.tcx.sess.parse_sess,
@@ -1665,7 +1665,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     )
                     .emit();
                 }
-                self.coroutine_kind = Some(hir::CoroutineKind::Coroutine);
+                false
+            }
+            None => {
+                if !self.tcx.features().coroutines {
+                    rustc_session::parse::feature_err(
+                        &self.tcx.sess.parse_sess,
+                        sym::coroutines,
+                        span,
+                        "yield syntax is experimental",
+                    )
+                    .emit();
+                }
+                self.coroutine_kind = Some(hir::CoroutineKind::Coroutine(Movability::Movable));
                 false
             }
         };
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 50da24a9f99..263bb153ca2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -848,7 +848,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         move_spans.var_subdiag(None, &mut err, None, |kind, var_span| {
             use crate::session_diagnostics::CaptureVarCause::*;
             match kind {
-                hir::ClosureKind::Coroutine(_, _) => MoveUseInCoroutine { var_span },
+                hir::ClosureKind::Coroutine(_) => MoveUseInCoroutine { var_span },
                 hir::ClosureKind::Closure => MoveUseInClosure { var_span },
             }
         });
@@ -893,7 +893,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             let place = &borrow.borrowed_place;
             let desc_place = self.describe_any_place(place.as_ref());
             match kind {
-                hir::ClosureKind::Coroutine(_, _) => {
+                hir::ClosureKind::Coroutine(_) => {
                     BorrowUsePlaceCoroutine { place: desc_place, var_span, is_single_var: true }
                 }
                 hir::ClosureKind::Closure => {
@@ -1042,7 +1042,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         |kind, var_span| {
                             use crate::session_diagnostics::CaptureVarCause::*;
                             match kind {
-                                hir::ClosureKind::Coroutine(_, _) => BorrowUsePlaceCoroutine {
+                                hir::ClosureKind::Coroutine(_) => BorrowUsePlaceCoroutine {
                                     place: desc_place,
                                     var_span,
                                     is_single_var: true,
@@ -1126,7 +1126,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             borrow_spans.var_subdiag(None, &mut err, Some(gen_borrow_kind), |kind, var_span| {
                 use crate::session_diagnostics::CaptureVarCause::*;
                 match kind {
-                    hir::ClosureKind::Coroutine(_, _) => BorrowUsePlaceCoroutine {
+                    hir::ClosureKind::Coroutine(_) => BorrowUsePlaceCoroutine {
                         place: desc_place,
                         var_span,
                         is_single_var: false,
@@ -1146,7 +1146,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     let borrow_place = &issued_borrow.borrowed_place;
                     let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
                     match kind {
-                        hir::ClosureKind::Coroutine(_, _) => {
+                        hir::ClosureKind::Coroutine(_) => {
                             FirstBorrowUsePlaceCoroutine { place: borrow_place_desc, var_span }
                         }
                         hir::ClosureKind::Closure => {
@@ -1163,7 +1163,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 |kind, var_span| {
                     use crate::session_diagnostics::CaptureVarCause::*;
                     match kind {
-                        hir::ClosureKind::Coroutine(_, _) => {
+                        hir::ClosureKind::Coroutine(_) => {
                             SecondBorrowUsePlaceCoroutine { place: desc_place, var_span }
                         }
                         hir::ClosureKind::Closure => {
@@ -2549,7 +2549,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         }
                     }
                 }
-                CoroutineKind::Coroutine => "coroutine",
+                CoroutineKind::Coroutine(_) => "coroutine",
             },
             None => "closure",
         };
@@ -2850,7 +2850,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
                     use crate::session_diagnostics::CaptureVarCause::*;
                     match kind {
-                        hir::ClosureKind::Coroutine(_, _) => BorrowUseInCoroutine { var_span },
+                        hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span },
                         hir::ClosureKind::Closure => BorrowUseInClosure { var_span },
                     }
                 });
@@ -2866,7 +2866,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
             use crate::session_diagnostics::CaptureVarCause::*;
             match kind {
-                hir::ClosureKind::Coroutine(_, _) => BorrowUseInCoroutine { var_span },
+                hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span },
                 hir::ClosureKind::Closure => BorrowUseInClosure { var_span },
             }
         });
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 0eb5e517164..da380ce4725 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -576,7 +576,7 @@ impl UseSpans<'_> {
     pub(super) fn coroutine_kind(self) -> Option<CoroutineKind> {
         match self {
             UseSpans::ClosureUse {
-                closure_kind: hir::ClosureKind::Coroutine(coroutine_kind, _),
+                closure_kind: hir::ClosureKind::Coroutine(coroutine_kind),
                 ..
             } => Some(coroutine_kind),
             _ => None,
@@ -605,7 +605,7 @@ impl UseSpans<'_> {
         use CaptureVarPathUseCause::*;
         if let UseSpans::ClosureUse { closure_kind, path_span, .. } = self {
             match closure_kind {
-                hir::ClosureKind::Coroutine(_, _) => {
+                hir::ClosureKind::Coroutine(_) => {
                     err.subdiagnostic(match action {
                         Borrow => BorrowInCoroutine { path_span },
                         MatchOn | Use => UseInCoroutine { path_span },
@@ -1248,7 +1248,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             // another message for the same span
             if !is_loop_message {
                 move_spans.var_subdiag(None, err, None, |kind, var_span| match kind {
-                    hir::ClosureKind::Coroutine(_, _) => {
+                    hir::ClosureKind::Coroutine(_) => {
                         CaptureVarCause::PartialMoveUseInCoroutine { var_span, is_partial }
                     }
                     hir::ClosureKind::Closure => {
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index c6ab52c67df..1835ecdb432 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -1047,10 +1047,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             }) => {
                 if !matches!(
                     kind,
-                    hir::ClosureKind::Coroutine(
-                        hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _),
+                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
+                        hir::CoroutineDesugaring::Async,
                         _
-                    )
+                    ),)
                 ) {
                     closure_span = Some(expr.span.shrink_to_lo());
                 }
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index f41def844e2..065c6635cf3 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -684,10 +684,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                     hir::FnRetTy::Return(hir_ty) => (fn_decl.output.span(), Some(hir_ty)),
                 };
                 let mir_description = match kind {
-                    hir::ClosureKind::Coroutine(
-                        hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, src),
-                        _,
-                    ) => match src {
+                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
+                        hir::CoroutineDesugaring::Async,
+                        src,
+                    )) => match src {
                         hir::CoroutineSource::Block => " of async block",
                         hir::CoroutineSource::Closure => " of async closure",
                         hir::CoroutineSource::Fn => {
@@ -704,10 +704,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                             " of async function"
                         }
                     },
-                    hir::ClosureKind::Coroutine(
-                        hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, src),
-                        _,
-                    ) => match src {
+                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
+                        hir::CoroutineDesugaring::Gen,
+                        src,
+                    )) => match src {
                         hir::CoroutineSource::Block => " of gen block",
                         hir::CoroutineSource::Closure => " of gen closure",
                         hir::CoroutineSource::Fn => {
@@ -722,10 +722,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                         }
                     },
 
-                    hir::ClosureKind::Coroutine(
-                        hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, src),
-                        _,
-                    ) => match src {
+                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
+                        hir::CoroutineDesugaring::AsyncGen,
+                        src,
+                    )) => match src {
                         hir::CoroutineSource::Block => " of async gen block",
                         hir::CoroutineSource::Closure => " of async gen closure",
                         hir::CoroutineSource::Fn => {
@@ -739,7 +739,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                             " of async gen function"
                         }
                     },
-                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine, _) => {
+                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_)) => {
                         " of coroutine"
                     }
                     hir::ClosureKind::Closure => " of closure",
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 2ecc5ad4fe4..ae71be14e64 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -585,7 +585,7 @@ fn coroutine_kind_label(coroutine_kind: Option<CoroutineKind>) -> &'static str {
         Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Fn)) => {
             "async_gen_fn"
         }
-        Some(CoroutineKind::Coroutine) => "coroutine",
+        Some(CoroutineKind::Coroutine(_)) => "coroutine",
         None => "closure",
     }
 }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index bf7adf8f44c..0f2b4512fea 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -938,8 +938,17 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
             TerminatorKind::InlineAsm { .. } => self.check_op(ops::InlineAsm),
 
-            TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } => {
-                self.check_op(ops::Coroutine(hir::CoroutineKind::Coroutine))
+            TerminatorKind::Yield { .. } => self.check_op(ops::Coroutine(
+                self.tcx
+                    .coroutine_kind(self.body.source.def_id())
+                    .expect("Only expected to have a yield in a coroutine"),
+            )),
+
+            TerminatorKind::CoroutineDrop => {
+                span_bug!(
+                    self.body.source_info(location).span,
+                    "We should not encounter TerminatorKind::CoroutineDrop after coroutine transform"
+                );
             }
 
             TerminatorKind::UnwindTerminate(_) => {
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 7b95fb33785..2b840860166 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -956,10 +956,7 @@ pub enum ClosureKind {
     /// we've found a `yield`. These can arise either from "plain" coroutine
     ///  usage (e.g. `let x = || { yield (); }`) or from a desugared expression
     /// (e.g. `async` and `gen` blocks).
-    // FIXME(coroutines): We could probably remove movability here -- it can be deduced
-    // from the `CoroutineKind` in all cases (except for "plain" coroutines, which could
-    // carry the movability in the variant).
-    Coroutine(CoroutineKind, Movability),
+    Coroutine(CoroutineKind),
 }
 
 /// A block of statements `{ .. }`, which may have a label (in this case the
@@ -1364,7 +1361,18 @@ pub enum CoroutineKind {
     Desugared(CoroutineDesugaring, CoroutineSource),
 
     /// A coroutine literal created via a `yield` inside a closure.
-    Coroutine,
+    Coroutine(Movability),
+}
+
+impl CoroutineKind {
+    pub fn movability(self) -> Movability {
+        match self {
+            CoroutineKind::Desugared(CoroutineDesugaring::Async, _)
+            | CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => Movability::Static,
+            CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => Movability::Movable,
+            CoroutineKind::Coroutine(mov) => mov,
+        }
+    }
 }
 
 impl fmt::Display for CoroutineKind {
@@ -1374,7 +1382,7 @@ impl fmt::Display for CoroutineKind {
                 d.fmt(f)?;
                 k.fmt(f)
             }
-            CoroutineKind::Coroutine => f.write_str("coroutine"),
+            CoroutineKind::Coroutine(_) => f.write_str("coroutine"),
         }
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 9fbe7b99a80..2908380edda 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1554,7 +1554,7 @@ fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineK
         Node::Expr(&hir::Expr {
             kind:
                 hir::ExprKind::Closure(&rustc_hir::Closure {
-                    kind: hir::ClosureKind::Coroutine(kind, _),
+                    kind: hir::ClosureKind::Coroutine(kind),
                     ..
                 }),
             ..
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 5a15a375baf..23b36f0e24d 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -343,7 +343,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
     {
         let dummy_args = match kind {
             ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..],
-            ClosureKind::Coroutine(_, _) => {
+            ClosureKind::Coroutine(_) => {
                 &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
             }
         };
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index a13e765df80..9913dd6444b 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -306,13 +306,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             let fn_decl_span = if matches!(
                 kind,
-                hir::ClosureKind::Coroutine(
-                    hir::CoroutineKind::Desugared(
-                        hir::CoroutineDesugaring::Async,
-                        hir::CoroutineSource::Closure
-                    ),
-                    _
-                )
+                hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
+                    hir::CoroutineDesugaring::Async,
+                    hir::CoroutineSource::Closure
+                ),)
             ) {
                 // Actually need to unwrap one more layer of HIR to get to
                 // the _real_ closure...
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 898ecf6ba87..f1dd29e512a 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -55,10 +55,10 @@ pub(super) fn check_fn<'a, 'tcx>(
 
     forbid_intrinsic_abi(tcx, span, fn_sig.abi);
 
-    if let Some(hir::ClosureKind::Coroutine(kind, _)) = closure_kind {
+    if let Some(hir::ClosureKind::Coroutine(kind)) = closure_kind {
         let yield_ty = match kind {
             hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)
-            | hir::CoroutineKind::Coroutine => {
+            | hir::CoroutineKind::Coroutine(_) => {
                 let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
                     kind: TypeVariableOriginKind::TypeInference,
                     span,
@@ -149,9 +149,7 @@ pub(super) fn check_fn<'a, 'tcx>(
     // We insert the deferred_coroutine_interiors entry after visiting the body.
     // This ensures that all nested coroutines appear before the entry of this coroutine.
     // resolve_coroutine_interiors relies on this property.
-    let coroutine_ty = if let Some(hir::ClosureKind::Coroutine(coroutine_kind, movability)) =
-        closure_kind
-    {
+    let coroutine_ty = if let Some(hir::ClosureKind::Coroutine(coroutine_kind)) = closure_kind {
         let interior = fcx
             .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
         fcx.deferred_coroutine_interiors.borrow_mut().push((
@@ -162,7 +160,12 @@ pub(super) fn check_fn<'a, 'tcx>(
         ));
 
         let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
-        Some(CoroutineTypes { resume_ty, yield_ty, interior, movability: movability })
+        Some(CoroutineTypes {
+            resume_ty,
+            yield_ty,
+            interior,
+            movability: coroutine_kind.movability(),
+        })
     } else {
         None
     };
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index fe07a868839..c29ef375ce4 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -638,13 +638,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // In the case of the async block that we create for a function body,
                 // we expect the return type of the block to match that of the enclosing
                 // function.
-                hir::ClosureKind::Coroutine(
-                    hir::CoroutineKind::Desugared(
-                        hir::CoroutineDesugaring::Async,
-                        hir::CoroutineSource::Fn,
-                    ),
-                    _,
-                ) => {
+                hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
+                    hir::CoroutineDesugaring::Async,
+                    hir::CoroutineSource::Fn,
+                )) => {
                     debug!("closure is async fn body");
                     self.deduce_future_output_from_obligations(expr_def_id).unwrap_or_else(|| {
                         // AFAIK, deducing the future output
@@ -661,17 +658,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 hir::ClosureKind::Coroutine(
                     hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)
                     | hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _),
-                    _,
                 ) => self.tcx.types.unit,
 
                 // For async blocks, we just fall back to `_` here.
                 // For closures/coroutines, we know nothing about the return
                 // type unless it was supplied.
-                hir::ClosureKind::Coroutine(
-                    hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _),
+                hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
+                    hir::CoroutineDesugaring::Async,
                     _,
-                )
-                | hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine, _)
+                ))
+                | hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_))
                 | hir::ClosureKind::Closure => astconv.ty_infer(None, decl.output.span()),
             },
         };
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 916ff469e09..306bf07a976 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -199,7 +199,8 @@ fixed_size_enum! {
 
 fixed_size_enum! {
     hir::CoroutineKind {
-        ( Coroutine                                                                    )
+        ( Coroutine(hir::Movability::Movable)                                          )
+        ( Coroutine(hir::Movability::Static)                                           )
         ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Block)        )
         ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Fn)           )
         ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Closure)      )
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index e0c9def0379..7be6deb6141 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -147,7 +147,7 @@ impl<O> AssertKind<O> {
             Overflow(op, _, _) => bug!("{:?} cannot overflow", op),
             DivisionByZero(_) => "attempt to divide by zero",
             RemainderByZero(_) => "attempt to calculate the remainder with a divisor of zero",
-            ResumedAfterReturn(CoroutineKind::Coroutine) => "coroutine resumed after completion",
+            ResumedAfterReturn(CoroutineKind::Coroutine(_)) => "coroutine resumed after completion",
             ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
                 "`async fn` resumed after completion"
             }
@@ -157,7 +157,7 @@ impl<O> AssertKind<O> {
             ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
                 "`gen fn` should just keep returning `None` after completion"
             }
-            ResumedAfterPanic(CoroutineKind::Coroutine) => "coroutine resumed after panicking",
+            ResumedAfterPanic(CoroutineKind::Coroutine(_)) => "coroutine resumed after panicking",
             ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
                 "`async fn` resumed after panicking"
             }
@@ -262,7 +262,7 @@ impl<O> AssertKind<O> {
             ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
                 bug!("gen blocks can be resumed after they return and will keep returning `None`")
             }
-            ResumedAfterReturn(CoroutineKind::Coroutine) => {
+            ResumedAfterReturn(CoroutineKind::Coroutine(_)) => {
                 middle_assert_coroutine_resume_after_return
             }
             ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
@@ -274,7 +274,7 @@ impl<O> AssertKind<O> {
             ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
                 middle_assert_gen_resume_after_panic
             }
-            ResumedAfterPanic(CoroutineKind::Coroutine) => {
+            ResumedAfterPanic(CoroutineKind::Coroutine(_)) => {
                 middle_assert_coroutine_resume_after_panic
             }
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 655dde1d9c9..12bf183a5aa 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -858,7 +858,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
     /// This means it is neither an `async` or `gen` construct.
     pub fn is_general_coroutine(self, def_id: DefId) -> bool {
-        matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine))
+        matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine(_)))
     }
 
     /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 8e045397b0f..13a5e881134 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -786,8 +786,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             ty::Coroutine(did, args, movability) => {
                 p!(write("{{"));
                 let coroutine_kind = self.tcx().coroutine_kind(did).unwrap();
-                let should_print_movability =
-                    self.should_print_verbose() || coroutine_kind == hir::CoroutineKind::Coroutine;
+                let should_print_movability = self.should_print_verbose()
+                    || matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_));
 
                 if should_print_movability {
                     match movability {
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index ab2488f2e91..907b26a2e7c 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -734,7 +734,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _) => {
                         "async gen closure"
                     }
-                    hir::CoroutineKind::Coroutine => "coroutine",
+                    hir::CoroutineKind::Coroutine(_) => "coroutine",
                     hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => {
                         "gen closure"
                     }
@@ -758,7 +758,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, ..) => "an",
                     hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, ..) => "an",
                     hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, ..) => "a",
-                    hir::CoroutineKind::Coroutine => "a",
+                    hir::CoroutineKind::Coroutine(_) => "a",
                 }
             }
             _ => def_kind.article(),
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 6da102dcb1c..367fa023da8 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -257,7 +257,7 @@ impl<'tcx> TransformVisitor<'tcx> {
             CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
                 span_bug!(body.span, "`Future`s are not fused inherently")
             }
-            CoroutineKind::Coroutine => span_bug!(body.span, "`Coroutine`s cannot be fused"),
+            CoroutineKind::Coroutine(_) => span_bug!(body.span, "`Coroutine`s cannot be fused"),
             // `gen` continues return `None`
             CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
                 let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
@@ -396,7 +396,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                     Rvalue::Use(val)
                 }
             }
-            CoroutineKind::Coroutine => {
+            CoroutineKind::Coroutine(_) => {
                 let coroutine_state_def_id =
                     self.tcx.require_lang_item(LangItem::CoroutineState, None);
                 let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]);
@@ -1428,7 +1428,8 @@ fn create_coroutine_resume_function<'tcx>(
 
     if can_return {
         let block = match coroutine_kind {
-            CoroutineKind::Desugared(CoroutineDesugaring::Async, _) | CoroutineKind::Coroutine => {
+            CoroutineKind::Desugared(CoroutineDesugaring::Async, _)
+            | CoroutineKind::Coroutine(_) => {
                 insert_panic_block(tcx, body, ResumedAfterReturn(coroutine_kind))
             }
             CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)
@@ -1643,7 +1644,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
                 // The yield ty is already `Poll<Option<yield_ty>>`
                 old_yield_ty
             }
-            CoroutineKind::Coroutine => {
+            CoroutineKind::Coroutine(_) => {
                 // Compute CoroutineState<yield_ty, return_ty>
                 let state_did = tcx.require_lang_item(LangItem::CoroutineState, None);
                 let state_adt_ref = tcx.adt_def(state_did);
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index b8b7e0d4580..69c58c5a36b 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -90,13 +90,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
             }) => {
                 // FIXME(coroutines): This doesn't handle coroutines correctly
                 let cx = match kind {
-                    hir::ClosureKind::Coroutine(
-                        hir::CoroutineKind::Desugared(
-                            hir::CoroutineDesugaring::Async,
-                            hir::CoroutineSource::Block,
-                        ),
-                        _,
-                    ) => AsyncClosure(fn_decl_span),
+                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
+                        hir::CoroutineDesugaring::Async,
+                        hir::CoroutineSource::Block,
+                    )) => AsyncClosure(fn_decl_span),
                     _ => Closure(fn_decl_span),
                 };
                 self.visit_fn_decl(fn_decl);
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
index 5f505ac181c..2446671770e 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
@@ -42,7 +42,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
     type T = stable_mir::mir::CoroutineKind;
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         use rustc_hir::{CoroutineDesugaring, CoroutineKind};
-        match self {
+        match *self {
             CoroutineKind::Desugared(CoroutineDesugaring::Async, source) => {
                 stable_mir::mir::CoroutineKind::Desugared(
                     stable_mir::mir::CoroutineDesugaring::Async,
@@ -55,7 +55,9 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
                     source.stable(tables),
                 )
             }
-            CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
+            CoroutineKind::Coroutine(movability) => {
+                stable_mir::mir::CoroutineKind::Coroutine(movability.stable(tables))
+            }
             CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, source) => {
                 stable_mir::mir::CoroutineKind::Desugared(
                     stable_mir::mir::CoroutineDesugaring::AsyncGen,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 97d67c2dad6..7e8936fbe6a 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2577,7 +2577,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             let message = outer_coroutine
                 .and_then(|coroutine_did| {
                     Some(match self.tcx.coroutine_kind(coroutine_did).unwrap() {
-                        CoroutineKind::Coroutine => format!("coroutine is not {trait_name}"),
+                        CoroutineKind::Coroutine(_) => format!("coroutine is not {trait_name}"),
                         CoroutineKind::Desugared(
                             CoroutineDesugaring::Async,
                             CoroutineSource::Fn,
@@ -3169,7 +3169,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             ObligationCauseCode::SizedCoroutineInterior(coroutine_def_id) => {
                 let what = match self.tcx.coroutine_kind(coroutine_def_id) {
                     None
-                    | Some(hir::CoroutineKind::Coroutine)
+                    | Some(hir::CoroutineKind::Coroutine(_))
                     | Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => {
                         "yield"
                     }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index f668c069f5b..29fc92cc765 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -1928,8 +1928,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     fn describe_closure(&self, kind: hir::ClosureKind) -> &'static str {
         match kind {
             hir::ClosureKind::Closure => "a closure",
-            hir::ClosureKind::Coroutine(kind, _) => match kind {
-                hir::CoroutineKind::Coroutine => "a coroutine",
+            hir::ClosureKind::Coroutine(kind) => match kind {
+                hir::CoroutineKind::Coroutine(_) => "a coroutine",
                 hir::CoroutineKind::Desugared(
                     hir::CoroutineDesugaring::Async,
                     hir::CoroutineSource::Block,
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 86501b5a72d..4756a45a447 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -121,7 +121,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 }
                 hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)
                 | hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)
-                | hir::CoroutineKind::Coroutine => Ty::new_adt(tcx, pin_adt_ref, pin_args),
+                | hir::CoroutineKind::Coroutine(_) => Ty::new_adt(tcx, pin_adt_ref, pin_args),
             };
 
             // The `FnSig` and the `ret_ty` here is for a coroutines main
@@ -192,7 +192,7 @@ fn fn_sig_for_fn_abi<'tcx>(
 
                     (Some(context_mut_ref), ret_ty)
                 }
-                hir::CoroutineKind::Coroutine => {
+                hir::CoroutineKind::Coroutine(_) => {
                     // The signature should be `Coroutine::resume(_, Resume) -> CoroutineState<Yield, Return>`
                     let state_did = tcx.require_lang_item(LangItem::CoroutineState, None);
                     let state_adt_ref = tcx.adt_def(state_did);
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 89d75569ce3..5871600bece 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -285,7 +285,7 @@ impl AssertMessage {
             AssertMessage::RemainderByZero(_) => {
                 Ok("attempt to calculate the remainder with a divisor of zero")
             }
-            AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine) => {
+            AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine(_)) => {
                 Ok("coroutine resumed after completion")
             }
             AssertMessage::ResumedAfterReturn(CoroutineKind::Desugared(
@@ -300,7 +300,7 @@ impl AssertMessage {
                 CoroutineDesugaring::AsyncGen,
                 _,
             )) => Ok("`gen fn` should just keep returning `AssertMessage::None` after completion"),
-            AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine) => {
+            AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine(_)) => {
                 Ok("coroutine resumed after panicking")
             }
             AssertMessage::ResumedAfterPanic(CoroutineKind::Desugared(
@@ -399,7 +399,7 @@ pub enum UnOp {
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum CoroutineKind {
     Desugared(CoroutineDesugaring, CoroutineSource),
-    Coroutine,
+    Coroutine(Movability),
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]