1
Fork 0

Only regular coroutines have movability

This commit is contained in:
Michael Goulet 2023-12-25 16:56:12 +00:00
parent 909dd864f1
commit 3320c09eab
25 changed files with 130 additions and 104 deletions

View file

@ -691,7 +691,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
body, body,
fn_decl_span: self.lower_span(span), fn_decl_span: self.lower_span(span),
fn_arg_span: None, fn_arg_span: None,
kind: hir::ClosureKind::Coroutine(coroutine_kind, Movability::Static), kind: hir::ClosureKind::Coroutine(coroutine_kind),
constness: hir::Constness::NotConst, constness: hir::Constness::NotConst,
})) }))
} }
@ -744,7 +744,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
body, body,
fn_decl_span: self.lower_span(span), fn_decl_span: self.lower_span(span),
fn_arg_span: None, fn_arg_span: None,
kind: hir::ClosureKind::Coroutine(coroutine_kind, Movability::Movable), kind: hir::ClosureKind::Coroutine(coroutine_kind),
constness: hir::Constness::NotConst, constness: hir::Constness::NotConst,
})) }))
} }
@ -829,7 +829,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
body, body,
fn_decl_span: self.lower_span(span), fn_decl_span: self.lower_span(span),
fn_arg_span: None, fn_arg_span: None,
kind: hir::ClosureKind::Coroutine(coroutine_kind, Movability::Static), kind: hir::ClosureKind::Coroutine(coroutine_kind),
constness: hir::Constness::NotConst, constness: hir::Constness::NotConst,
})) }))
} }
@ -898,7 +898,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let is_async_gen = match self.coroutine_kind { let is_async_gen = match self.coroutine_kind {
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => false, Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => false,
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true, Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
Some(hir::CoroutineKind::Coroutine) Some(hir::CoroutineKind::Coroutine(_))
| Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) | Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
| None => { | None => {
return hir::ExprKind::Err(self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks { return hir::ExprKind::Err(self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
@ -1126,11 +1126,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
movability: Movability, movability: Movability,
) -> hir::ClosureKind { ) -> hir::ClosureKind {
match coroutine_kind { match coroutine_kind {
Some(hir::CoroutineKind::Coroutine) => { Some(hir::CoroutineKind::Coroutine(_)) => {
if decl.inputs.len() > 1 { if decl.inputs.len() > 1 {
self.tcx.sess.emit_err(CoroutineTooManyParameters { fn_decl_span }); self.tcx.sess.emit_err(CoroutineTooManyParameters { fn_decl_span });
} }
hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine, movability) hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(movability))
} }
Some( Some(
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)
@ -1655,7 +1655,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span }), self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span }),
); );
} }
Some(hir::CoroutineKind::Coroutine) | None => { Some(hir::CoroutineKind::Coroutine(_)) => {
if !self.tcx.features().coroutines { if !self.tcx.features().coroutines {
rustc_session::parse::feature_err( rustc_session::parse::feature_err(
&self.tcx.sess.parse_sess, &self.tcx.sess.parse_sess,
@ -1665,7 +1665,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
) )
.emit(); .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 false
} }
}; };

View file

@ -848,7 +848,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
move_spans.var_subdiag(None, &mut err, None, |kind, var_span| { move_spans.var_subdiag(None, &mut err, None, |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*; use crate::session_diagnostics::CaptureVarCause::*;
match kind { match kind {
hir::ClosureKind::Coroutine(_, _) => MoveUseInCoroutine { var_span }, hir::ClosureKind::Coroutine(_) => MoveUseInCoroutine { var_span },
hir::ClosureKind::Closure => MoveUseInClosure { var_span }, hir::ClosureKind::Closure => MoveUseInClosure { var_span },
} }
}); });
@ -893,7 +893,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let place = &borrow.borrowed_place; let place = &borrow.borrowed_place;
let desc_place = self.describe_any_place(place.as_ref()); let desc_place = self.describe_any_place(place.as_ref());
match kind { match kind {
hir::ClosureKind::Coroutine(_, _) => { hir::ClosureKind::Coroutine(_) => {
BorrowUsePlaceCoroutine { place: desc_place, var_span, is_single_var: true } BorrowUsePlaceCoroutine { place: desc_place, var_span, is_single_var: true }
} }
hir::ClosureKind::Closure => { hir::ClosureKind::Closure => {
@ -1042,7 +1042,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|kind, var_span| { |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*; use crate::session_diagnostics::CaptureVarCause::*;
match kind { match kind {
hir::ClosureKind::Coroutine(_, _) => BorrowUsePlaceCoroutine { hir::ClosureKind::Coroutine(_) => BorrowUsePlaceCoroutine {
place: desc_place, place: desc_place,
var_span, var_span,
is_single_var: true, 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| { borrow_spans.var_subdiag(None, &mut err, Some(gen_borrow_kind), |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*; use crate::session_diagnostics::CaptureVarCause::*;
match kind { match kind {
hir::ClosureKind::Coroutine(_, _) => BorrowUsePlaceCoroutine { hir::ClosureKind::Coroutine(_) => BorrowUsePlaceCoroutine {
place: desc_place, place: desc_place,
var_span, var_span,
is_single_var: false, is_single_var: false,
@ -1146,7 +1146,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let borrow_place = &issued_borrow.borrowed_place; let borrow_place = &issued_borrow.borrowed_place;
let borrow_place_desc = self.describe_any_place(borrow_place.as_ref()); let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
match kind { match kind {
hir::ClosureKind::Coroutine(_, _) => { hir::ClosureKind::Coroutine(_) => {
FirstBorrowUsePlaceCoroutine { place: borrow_place_desc, var_span } FirstBorrowUsePlaceCoroutine { place: borrow_place_desc, var_span }
} }
hir::ClosureKind::Closure => { hir::ClosureKind::Closure => {
@ -1163,7 +1163,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|kind, var_span| { |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*; use crate::session_diagnostics::CaptureVarCause::*;
match kind { match kind {
hir::ClosureKind::Coroutine(_, _) => { hir::ClosureKind::Coroutine(_) => {
SecondBorrowUsePlaceCoroutine { place: desc_place, var_span } SecondBorrowUsePlaceCoroutine { place: desc_place, var_span }
} }
hir::ClosureKind::Closure => { hir::ClosureKind::Closure => {
@ -2549,7 +2549,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
} }
} }
CoroutineKind::Coroutine => "coroutine", CoroutineKind::Coroutine(_) => "coroutine",
}, },
None => "closure", 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| { loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*; use crate::session_diagnostics::CaptureVarCause::*;
match kind { match kind {
hir::ClosureKind::Coroutine(_, _) => BorrowUseInCoroutine { var_span }, hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span },
hir::ClosureKind::Closure => BorrowUseInClosure { 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| { loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
use crate::session_diagnostics::CaptureVarCause::*; use crate::session_diagnostics::CaptureVarCause::*;
match kind { match kind {
hir::ClosureKind::Coroutine(_, _) => BorrowUseInCoroutine { var_span }, hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span },
hir::ClosureKind::Closure => BorrowUseInClosure { var_span }, hir::ClosureKind::Closure => BorrowUseInClosure { var_span },
} }
}); });

View file

@ -576,7 +576,7 @@ impl UseSpans<'_> {
pub(super) fn coroutine_kind(self) -> Option<CoroutineKind> { pub(super) fn coroutine_kind(self) -> Option<CoroutineKind> {
match self { match self {
UseSpans::ClosureUse { UseSpans::ClosureUse {
closure_kind: hir::ClosureKind::Coroutine(coroutine_kind, _), closure_kind: hir::ClosureKind::Coroutine(coroutine_kind),
.. ..
} => Some(coroutine_kind), } => Some(coroutine_kind),
_ => None, _ => None,
@ -605,7 +605,7 @@ impl UseSpans<'_> {
use CaptureVarPathUseCause::*; use CaptureVarPathUseCause::*;
if let UseSpans::ClosureUse { closure_kind, path_span, .. } = self { if let UseSpans::ClosureUse { closure_kind, path_span, .. } = self {
match closure_kind { match closure_kind {
hir::ClosureKind::Coroutine(_, _) => { hir::ClosureKind::Coroutine(_) => {
err.subdiagnostic(match action { err.subdiagnostic(match action {
Borrow => BorrowInCoroutine { path_span }, Borrow => BorrowInCoroutine { path_span },
MatchOn | Use => UseInCoroutine { path_span }, MatchOn | Use => UseInCoroutine { path_span },
@ -1248,7 +1248,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// another message for the same span // another message for the same span
if !is_loop_message { if !is_loop_message {
move_spans.var_subdiag(None, err, None, |kind, var_span| match kind { move_spans.var_subdiag(None, err, None, |kind, var_span| match kind {
hir::ClosureKind::Coroutine(_, _) => { hir::ClosureKind::Coroutine(_) => {
CaptureVarCause::PartialMoveUseInCoroutine { var_span, is_partial } CaptureVarCause::PartialMoveUseInCoroutine { var_span, is_partial }
} }
hir::ClosureKind::Closure => { hir::ClosureKind::Closure => {

View file

@ -1047,10 +1047,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}) => { }) => {
if !matches!( if !matches!(
kind, kind,
hir::ClosureKind::Coroutine( hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _), hir::CoroutineDesugaring::Async,
_ _
) ),)
) { ) {
closure_span = Some(expr.span.shrink_to_lo()); closure_span = Some(expr.span.shrink_to_lo());
} }

View file

@ -684,10 +684,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
hir::FnRetTy::Return(hir_ty) => (fn_decl.output.span(), Some(hir_ty)), hir::FnRetTy::Return(hir_ty) => (fn_decl.output.span(), Some(hir_ty)),
}; };
let mir_description = match kind { let mir_description = match kind {
hir::ClosureKind::Coroutine( hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, src), hir::CoroutineDesugaring::Async,
_, src,
) => match src { )) => match src {
hir::CoroutineSource::Block => " of async block", hir::CoroutineSource::Block => " of async block",
hir::CoroutineSource::Closure => " of async closure", hir::CoroutineSource::Closure => " of async closure",
hir::CoroutineSource::Fn => { hir::CoroutineSource::Fn => {
@ -704,10 +704,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
" of async function" " of async function"
} }
}, },
hir::ClosureKind::Coroutine( hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, src), hir::CoroutineDesugaring::Gen,
_, src,
) => match src { )) => match src {
hir::CoroutineSource::Block => " of gen block", hir::CoroutineSource::Block => " of gen block",
hir::CoroutineSource::Closure => " of gen closure", hir::CoroutineSource::Closure => " of gen closure",
hir::CoroutineSource::Fn => { hir::CoroutineSource::Fn => {
@ -722,10 +722,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
} }
}, },
hir::ClosureKind::Coroutine( hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, src), hir::CoroutineDesugaring::AsyncGen,
_, src,
) => match src { )) => match src {
hir::CoroutineSource::Block => " of async gen block", hir::CoroutineSource::Block => " of async gen block",
hir::CoroutineSource::Closure => " of async gen closure", hir::CoroutineSource::Closure => " of async gen closure",
hir::CoroutineSource::Fn => { hir::CoroutineSource::Fn => {
@ -739,7 +739,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
" of async gen function" " of async gen function"
} }
}, },
hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine, _) => { hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_)) => {
" of coroutine" " of coroutine"
} }
hir::ClosureKind::Closure => " of closure", hir::ClosureKind::Closure => " of closure",

View file

@ -585,7 +585,7 @@ fn coroutine_kind_label(coroutine_kind: Option<CoroutineKind>) -> &'static str {
Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Fn)) => { Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Fn)) => {
"async_gen_fn" "async_gen_fn"
} }
Some(CoroutineKind::Coroutine) => "coroutine", Some(CoroutineKind::Coroutine(_)) => "coroutine",
None => "closure", None => "closure",
} }
} }

View file

@ -938,8 +938,17 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
TerminatorKind::InlineAsm { .. } => self.check_op(ops::InlineAsm), TerminatorKind::InlineAsm { .. } => self.check_op(ops::InlineAsm),
TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } => { TerminatorKind::Yield { .. } => self.check_op(ops::Coroutine(
self.check_op(ops::Coroutine(hir::CoroutineKind::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(_) => { TerminatorKind::UnwindTerminate(_) => {

View file

@ -956,10 +956,7 @@ pub enum ClosureKind {
/// we've found a `yield`. These can arise either from "plain" coroutine /// we've found a `yield`. These can arise either from "plain" coroutine
/// usage (e.g. `let x = || { yield (); }`) or from a desugared expression /// usage (e.g. `let x = || { yield (); }`) or from a desugared expression
/// (e.g. `async` and `gen` blocks). /// (e.g. `async` and `gen` blocks).
// FIXME(coroutines): We could probably remove movability here -- it can be deduced Coroutine(CoroutineKind),
// from the `CoroutineKind` in all cases (except for "plain" coroutines, which could
// carry the movability in the variant).
Coroutine(CoroutineKind, Movability),
} }
/// A block of statements `{ .. }`, which may have a label (in this case the /// A block of statements `{ .. }`, which may have a label (in this case the
@ -1364,7 +1361,18 @@ pub enum CoroutineKind {
Desugared(CoroutineDesugaring, CoroutineSource), Desugared(CoroutineDesugaring, CoroutineSource),
/// A coroutine literal created via a `yield` inside a closure. /// 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 { impl fmt::Display for CoroutineKind {
@ -1374,7 +1382,7 @@ impl fmt::Display for CoroutineKind {
d.fmt(f)?; d.fmt(f)?;
k.fmt(f) k.fmt(f)
} }
CoroutineKind::Coroutine => f.write_str("coroutine"), CoroutineKind::Coroutine(_) => f.write_str("coroutine"),
} }
} }
} }

View file

@ -1554,7 +1554,7 @@ fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineK
Node::Expr(&hir::Expr { Node::Expr(&hir::Expr {
kind: kind:
hir::ExprKind::Closure(&rustc_hir::Closure { hir::ExprKind::Closure(&rustc_hir::Closure {
kind: hir::ClosureKind::Coroutine(kind, _), kind: hir::ClosureKind::Coroutine(kind),
.. ..
}), }),
.. ..

View file

@ -343,7 +343,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
{ {
let dummy_args = match kind { let dummy_args = match kind {
ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..], ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..],
ClosureKind::Coroutine(_, _) => { ClosureKind::Coroutine(_) => {
&["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..] &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
} }
}; };

View file

@ -306,13 +306,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{ {
let fn_decl_span = if matches!( let fn_decl_span = if matches!(
kind, kind,
hir::ClosureKind::Coroutine( hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
hir::CoroutineKind::Desugared( hir::CoroutineDesugaring::Async,
hir::CoroutineDesugaring::Async, hir::CoroutineSource::Closure
hir::CoroutineSource::Closure ),)
),
_
)
) { ) {
// Actually need to unwrap one more layer of HIR to get to // Actually need to unwrap one more layer of HIR to get to
// the _real_ closure... // the _real_ closure...

View file

@ -55,10 +55,10 @@ pub(super) fn check_fn<'a, 'tcx>(
forbid_intrinsic_abi(tcx, span, fn_sig.abi); 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 { let yield_ty = match kind {
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)
| hir::CoroutineKind::Coroutine => { | hir::CoroutineKind::Coroutine(_) => {
let yield_ty = fcx.next_ty_var(TypeVariableOrigin { let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference, kind: TypeVariableOriginKind::TypeInference,
span, span,
@ -149,9 +149,7 @@ pub(super) fn check_fn<'a, 'tcx>(
// We insert the deferred_coroutine_interiors entry after visiting the body. // We insert the deferred_coroutine_interiors entry after visiting the body.
// This ensures that all nested coroutines appear before the entry of this coroutine. // This ensures that all nested coroutines appear before the entry of this coroutine.
// resolve_coroutine_interiors relies on this property. // resolve_coroutine_interiors relies on this property.
let coroutine_ty = if let Some(hir::ClosureKind::Coroutine(coroutine_kind, movability)) = let coroutine_ty = if let Some(hir::ClosureKind::Coroutine(coroutine_kind)) = closure_kind {
closure_kind
{
let interior = fcx let interior = fcx
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span }); .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
fcx.deferred_coroutine_interiors.borrow_mut().push(( 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(); 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 { } else {
None None
}; };

View file

@ -638,13 +638,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// In the case of the async block that we create for a function body, // 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 // we expect the return type of the block to match that of the enclosing
// function. // function.
hir::ClosureKind::Coroutine( hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
hir::CoroutineKind::Desugared( hir::CoroutineDesugaring::Async,
hir::CoroutineDesugaring::Async, hir::CoroutineSource::Fn,
hir::CoroutineSource::Fn, )) => {
),
_,
) => {
debug!("closure is async fn body"); debug!("closure is async fn body");
self.deduce_future_output_from_obligations(expr_def_id).unwrap_or_else(|| { self.deduce_future_output_from_obligations(expr_def_id).unwrap_or_else(|| {
// AFAIK, deducing the future output // AFAIK, deducing the future output
@ -661,17 +658,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::ClosureKind::Coroutine( hir::ClosureKind::Coroutine(
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)
| hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _), | hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _),
_,
) => self.tcx.types.unit, ) => self.tcx.types.unit,
// For async blocks, we just fall back to `_` here. // For async blocks, we just fall back to `_` here.
// For closures/coroutines, we know nothing about the return // For closures/coroutines, we know nothing about the return
// type unless it was supplied. // type unless it was supplied.
hir::ClosureKind::Coroutine( hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _), 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()), | hir::ClosureKind::Closure => astconv.ty_infer(None, decl.output.span()),
}, },
}; };

View file

@ -199,7 +199,8 @@ fixed_size_enum! {
fixed_size_enum! { fixed_size_enum! {
hir::CoroutineKind { hir::CoroutineKind {
( Coroutine ) ( Coroutine(hir::Movability::Movable) )
( Coroutine(hir::Movability::Static) )
( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Block) ) ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Block) )
( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Fn) ) ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Fn) )
( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Closure) ) ( Desugared(hir::CoroutineDesugaring::Gen, hir::CoroutineSource::Closure) )

View file

@ -147,7 +147,7 @@ impl<O> AssertKind<O> {
Overflow(op, _, _) => bug!("{:?} cannot overflow", op), Overflow(op, _, _) => bug!("{:?} cannot overflow", op),
DivisionByZero(_) => "attempt to divide by zero", DivisionByZero(_) => "attempt to divide by zero",
RemainderByZero(_) => "attempt to calculate the remainder with a divisor of 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, _)) => { ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
"`async fn` resumed after completion" "`async fn` resumed after completion"
} }
@ -157,7 +157,7 @@ impl<O> AssertKind<O> {
ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
"`gen fn` should just keep returning `None` after completion" "`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, _)) => { ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
"`async fn` resumed after panicking" "`async fn` resumed after panicking"
} }
@ -262,7 +262,7 @@ impl<O> AssertKind<O> {
ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
bug!("gen blocks can be resumed after they return and will keep returning `None`") 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 middle_assert_coroutine_resume_after_return
} }
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
@ -274,7 +274,7 @@ impl<O> AssertKind<O> {
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
middle_assert_gen_resume_after_panic middle_assert_gen_resume_after_panic
} }
ResumedAfterPanic(CoroutineKind::Coroutine) => { ResumedAfterPanic(CoroutineKind::Coroutine(_)) => {
middle_assert_coroutine_resume_after_panic middle_assert_coroutine_resume_after_panic
} }

View file

@ -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`. /// 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. /// This means it is neither an `async` or `gen` construct.
pub fn is_general_coroutine(self, def_id: DefId) -> bool { 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. /// Returns `true` if the node pointed to by `def_id` is a coroutine for a `gen` construct.

View file

@ -786,8 +786,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
ty::Coroutine(did, args, movability) => { ty::Coroutine(did, args, movability) => {
p!(write("{{")); p!(write("{{"));
let coroutine_kind = self.tcx().coroutine_kind(did).unwrap(); let coroutine_kind = self.tcx().coroutine_kind(did).unwrap();
let should_print_movability = let should_print_movability = self.should_print_verbose()
self.should_print_verbose() || coroutine_kind == hir::CoroutineKind::Coroutine; || matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_));
if should_print_movability { if should_print_movability {
match movability { match movability {

View file

@ -734,7 +734,7 @@ impl<'tcx> TyCtxt<'tcx> {
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _) => { hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _) => {
"async gen closure" "async gen closure"
} }
hir::CoroutineKind::Coroutine => "coroutine", hir::CoroutineKind::Coroutine(_) => "coroutine",
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => { hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) => {
"gen closure" "gen closure"
} }
@ -758,7 +758,7 @@ impl<'tcx> TyCtxt<'tcx> {
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, ..) => "an", hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, ..) => "an",
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, ..) => "an", hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, ..) => "an",
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, ..) => "a", hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, ..) => "a",
hir::CoroutineKind::Coroutine => "a", hir::CoroutineKind::Coroutine(_) => "a",
} }
} }
_ => def_kind.article(), _ => def_kind.article(),

View file

@ -257,7 +257,7 @@ impl<'tcx> TransformVisitor<'tcx> {
CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => { CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
span_bug!(body.span, "`Future`s are not fused inherently") 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` // `gen` continues return `None`
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
let option_def_id = self.tcx.require_lang_item(LangItem::Option, None); let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
@ -396,7 +396,7 @@ impl<'tcx> TransformVisitor<'tcx> {
Rvalue::Use(val) Rvalue::Use(val)
} }
} }
CoroutineKind::Coroutine => { CoroutineKind::Coroutine(_) => {
let coroutine_state_def_id = let coroutine_state_def_id =
self.tcx.require_lang_item(LangItem::CoroutineState, None); self.tcx.require_lang_item(LangItem::CoroutineState, None);
let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]); 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 { if can_return {
let block = match coroutine_kind { 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)) insert_panic_block(tcx, body, ResumedAfterReturn(coroutine_kind))
} }
CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)
@ -1643,7 +1644,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
// The yield ty is already `Poll<Option<yield_ty>>` // The yield ty is already `Poll<Option<yield_ty>>`
old_yield_ty old_yield_ty
} }
CoroutineKind::Coroutine => { CoroutineKind::Coroutine(_) => {
// Compute CoroutineState<yield_ty, return_ty> // Compute CoroutineState<yield_ty, return_ty>
let state_did = tcx.require_lang_item(LangItem::CoroutineState, None); let state_did = tcx.require_lang_item(LangItem::CoroutineState, None);
let state_adt_ref = tcx.adt_def(state_did); let state_adt_ref = tcx.adt_def(state_did);

View file

@ -90,13 +90,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
}) => { }) => {
// FIXME(coroutines): This doesn't handle coroutines correctly // FIXME(coroutines): This doesn't handle coroutines correctly
let cx = match kind { let cx = match kind {
hir::ClosureKind::Coroutine( hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
hir::CoroutineKind::Desugared( hir::CoroutineDesugaring::Async,
hir::CoroutineDesugaring::Async, hir::CoroutineSource::Block,
hir::CoroutineSource::Block, )) => AsyncClosure(fn_decl_span),
),
_,
) => AsyncClosure(fn_decl_span),
_ => Closure(fn_decl_span), _ => Closure(fn_decl_span),
}; };
self.visit_fn_decl(fn_decl); self.visit_fn_decl(fn_decl);

View file

@ -42,7 +42,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
type T = stable_mir::mir::CoroutineKind; type T = stable_mir::mir::CoroutineKind;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use rustc_hir::{CoroutineDesugaring, CoroutineKind}; use rustc_hir::{CoroutineDesugaring, CoroutineKind};
match self { match *self {
CoroutineKind::Desugared(CoroutineDesugaring::Async, source) => { CoroutineKind::Desugared(CoroutineDesugaring::Async, source) => {
stable_mir::mir::CoroutineKind::Desugared( stable_mir::mir::CoroutineKind::Desugared(
stable_mir::mir::CoroutineDesugaring::Async, stable_mir::mir::CoroutineDesugaring::Async,
@ -55,7 +55,9 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
source.stable(tables), 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) => { CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, source) => {
stable_mir::mir::CoroutineKind::Desugared( stable_mir::mir::CoroutineKind::Desugared(
stable_mir::mir::CoroutineDesugaring::AsyncGen, stable_mir::mir::CoroutineDesugaring::AsyncGen,

View file

@ -2577,7 +2577,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let message = outer_coroutine let message = outer_coroutine
.and_then(|coroutine_did| { .and_then(|coroutine_did| {
Some(match self.tcx.coroutine_kind(coroutine_did).unwrap() { 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( CoroutineKind::Desugared(
CoroutineDesugaring::Async, CoroutineDesugaring::Async,
CoroutineSource::Fn, CoroutineSource::Fn,
@ -3169,7 +3169,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ObligationCauseCode::SizedCoroutineInterior(coroutine_def_id) => { ObligationCauseCode::SizedCoroutineInterior(coroutine_def_id) => {
let what = match self.tcx.coroutine_kind(coroutine_def_id) { let what = match self.tcx.coroutine_kind(coroutine_def_id) {
None None
| Some(hir::CoroutineKind::Coroutine) | Some(hir::CoroutineKind::Coroutine(_))
| Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => { | Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => {
"yield" "yield"
} }

View file

@ -1928,8 +1928,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
fn describe_closure(&self, kind: hir::ClosureKind) -> &'static str { fn describe_closure(&self, kind: hir::ClosureKind) -> &'static str {
match kind { match kind {
hir::ClosureKind::Closure => "a closure", hir::ClosureKind::Closure => "a closure",
hir::ClosureKind::Coroutine(kind, _) => match kind { hir::ClosureKind::Coroutine(kind) => match kind {
hir::CoroutineKind::Coroutine => "a coroutine", hir::CoroutineKind::Coroutine(_) => "a coroutine",
hir::CoroutineKind::Desugared( hir::CoroutineKind::Desugared(
hir::CoroutineDesugaring::Async, hir::CoroutineDesugaring::Async,
hir::CoroutineSource::Block, hir::CoroutineSource::Block,

View file

@ -121,7 +121,7 @@ fn fn_sig_for_fn_abi<'tcx>(
} }
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _) hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)
| hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _) | 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 // 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) (Some(context_mut_ref), ret_ty)
} }
hir::CoroutineKind::Coroutine => { hir::CoroutineKind::Coroutine(_) => {
// The signature should be `Coroutine::resume(_, Resume) -> CoroutineState<Yield, Return>` // The signature should be `Coroutine::resume(_, Resume) -> CoroutineState<Yield, Return>`
let state_did = tcx.require_lang_item(LangItem::CoroutineState, None); let state_did = tcx.require_lang_item(LangItem::CoroutineState, None);
let state_adt_ref = tcx.adt_def(state_did); let state_adt_ref = tcx.adt_def(state_did);

View file

@ -285,7 +285,7 @@ impl AssertMessage {
AssertMessage::RemainderByZero(_) => { AssertMessage::RemainderByZero(_) => {
Ok("attempt to calculate the remainder with a divisor of zero") Ok("attempt to calculate the remainder with a divisor of zero")
} }
AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine) => { AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine(_)) => {
Ok("coroutine resumed after completion") Ok("coroutine resumed after completion")
} }
AssertMessage::ResumedAfterReturn(CoroutineKind::Desugared( AssertMessage::ResumedAfterReturn(CoroutineKind::Desugared(
@ -300,7 +300,7 @@ impl AssertMessage {
CoroutineDesugaring::AsyncGen, CoroutineDesugaring::AsyncGen,
_, _,
)) => Ok("`gen fn` should just keep returning `AssertMessage::None` after completion"), )) => Ok("`gen fn` should just keep returning `AssertMessage::None` after completion"),
AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine) => { AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine(_)) => {
Ok("coroutine resumed after panicking") Ok("coroutine resumed after panicking")
} }
AssertMessage::ResumedAfterPanic(CoroutineKind::Desugared( AssertMessage::ResumedAfterPanic(CoroutineKind::Desugared(
@ -399,7 +399,7 @@ pub enum UnOp {
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub enum CoroutineKind { pub enum CoroutineKind {
Desugared(CoroutineDesugaring, CoroutineSource), Desugared(CoroutineDesugaring, CoroutineSource),
Coroutine, Coroutine(Movability),
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]