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:
commit
1ab783112a
47 changed files with 573 additions and 491 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue