1
Fork 0

Auto merge of #119258 - compiler-errors:closure-kind, r=eholk

Make closures carry their own ClosureKind

Right now, we use the "`movability`" field of `hir::Closure` to distinguish a closure and a coroutine. This is paired together with the `CoroutineKind`, which is located not in the `hir::Closure`, but the `hir::Body`. This is strange and redundant.

This PR introduces `ClosureKind` with two variants -- `Closure` and `Coroutine`, which is put into `hir::Closure`. The `CoroutineKind` is thus removed from `hir::Body`, and `Option<Movability>` no longer needs to be a stand-in for "is this a closure or a coroutine".

r? eholk
This commit is contained in:
bors 2023-12-26 04:25:53 +00:00
commit 1ab783112a
47 changed files with 573 additions and 491 deletions

View file

@ -307,11 +307,6 @@ pub struct ScopeTree {
/// the values are still owned by their containing expressions. So
/// we'll see that `&x`.
pub yield_in_scope: FxHashMap<Scope, Vec<YieldData>>,
/// The number of visit_expr and visit_pat calls done in the body.
/// Used to sanity check visit_expr/visit_pat call count when
/// calculating coroutine interiors.
pub body_expr_count: FxHashMap<hir::BodyId, usize>,
}
/// Identifies the reason that a given expression is an rvalue candidate
@ -408,20 +403,12 @@ impl ScopeTree {
pub fn yield_in_scope(&self, scope: Scope) -> Option<&[YieldData]> {
self.yield_in_scope.get(&scope).map(Deref::deref)
}
/// Gives the number of expressions visited in a body.
/// Used to sanity check visit_expr call count when
/// calculating coroutine interiors.
pub fn body_expr_count(&self, body_id: hir::BodyId) -> Option<usize> {
self.body_expr_count.get(&body_id).copied()
}
}
impl<'a> HashStable<StableHashingContext<'a>> for ScopeTree {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
let ScopeTree {
root_body,
ref body_expr_count,
ref parent_map,
ref var_map,
ref destruction_scopes,
@ -430,7 +417,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for ScopeTree {
} = *self;
root_body.hash_stable(hcx, hasher);
body_expr_count.hash_stable(hcx, hasher);
parent_map.hash_stable(hcx, hasher);
var_map.hash_stable(hcx, hasher);
destruction_scopes.hash_stable(hcx, hasher);

View file

@ -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
}

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`.
/// 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.

View file

@ -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 {

View file

@ -735,7 +735,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"
}
@ -759,7 +759,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(),