Skip to content

Commit 3320398

Browse files
committed
Deconstruct Escapable check for coroutines with normal results
1 parent e7cd1c5 commit 3320398

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

lib/AST/Decl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11457,8 +11457,8 @@ Type FuncDecl::getYieldsInterfaceType() const {
1145711457
}
1145811458

1145911459
llvm_unreachable("coroutine must have a yield result");
11460-
} else if (!resultType->is<YieldResultType>()) {
11461-
resultType = TupleType::getEmpty(getASTContext());
11460+
} else if (resultType->is<YieldResultType>()) {
11461+
return resultType;
1146211462
}
1146311463

1146411464
return resultType;

lib/AST/LifetimeDependence.cpp

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,8 @@ class LifetimeDependenceChecker {
677677
// needs one. Always runs before the checker completes if no other diagnostics
678678
// were issued.
679679
void diagnoseMissingResultDependencies(DiagID diagID) {
680-
if (!isDiagnosedNonEscapable(getResultOrYield())) {
680+
if (!isDiagnosedNonEscapable(getResultWithoutYield()) &&
681+
!isDiagnosedNonEscapable(getYields())) {
681682
return;
682683
}
683684
if (!depBuilder.hasTargetDeps(resultIndex)) {
@@ -789,23 +790,35 @@ class LifetimeDependenceChecker {
789790
loweredOwnership == ValueOwnership::InOut;
790791
}
791792

792-
Type getResultOrYield() const {
793+
Type getResultWithoutYield() const {
793794
auto *afd = cast<AbstractFunctionDecl>(decl);
794-
if (auto *accessor = dyn_cast<AccessorDecl>(afd)) {
795-
if (accessor->isCoroutine()) {
796-
auto yieldTyInContext = accessor->mapTypeIntoContext(
797-
accessor->getStorage()->getValueInterfaceType());
798-
return yieldTyInContext;
799-
}
800-
}
801795
Type resultType;
802796
if (auto fn = dyn_cast<FuncDecl>(afd)) {
803-
resultType = fn->getResultInterfaceType();
797+
resultType = fn->getResultInterfaceTypeWithoutYields();
804798
} else {
805799
auto ctor = cast<ConstructorDecl>(afd);
806800
resultType = ctor->getResultInterfaceType();
807801
}
808-
return afd->mapTypeIntoContext(resultType);
802+
resultType = afd->mapTypeIntoContext(resultType);
803+
if (resultType->isEqual(afd->getASTContext().TheEmptyTupleType))
804+
return ErrorType::get(afd->getASTContext());
805+
806+
return resultType;
807+
}
808+
809+
Type getYields() const {
810+
auto *afd = cast<AbstractFunctionDecl>(decl);
811+
if (auto fn = dyn_cast<FuncDecl>(afd)) {
812+
auto yieldType = afd->mapTypeIntoContext(fn->getYieldsInterfaceType());
813+
if (yieldType->isEqual(afd->getASTContext().TheEmptyTupleType))
814+
return ErrorType::get(afd->getASTContext());
815+
816+
if (yieldType->hasError())
817+
return yieldType;
818+
819+
return yieldType->getAs<YieldResultType>()->getResultType();
820+
}
821+
return ErrorType::get(afd->getASTContext());
809822
}
810823

811824
// ==========================================================================
@@ -973,10 +986,14 @@ class LifetimeDependenceChecker {
973986
}
974987
targetIndex = targetDeclAndIndex->second;
975988
} else {
976-
if (isDiagnosedEscapable(getResultOrYield())) {
989+
if (isDiagnosedEscapable(getResultWithoutYield())) {
977990
diagnose(entry->getLoc(), diag::lifetime_target_requires_nonescapable,
978991
"result");
992+
} else if (isDiagnosedEscapable(getYields())) {
993+
diagnose(entry->getLoc(), diag::lifetime_target_requires_nonescapable,
994+
"yield");
979995
}
996+
980997
targetIndex = afd->hasImplicitSelfDecl()
981998
? afd->getParameters()->size() + 1
982999
: afd->getParameters()->size();
@@ -1103,7 +1120,8 @@ class LifetimeDependenceChecker {
11031120
}
11041121

11051122
// Infer non-Escapable results.
1106-
if (isDiagnosedNonEscapable(getResultOrYield())) {
1123+
if (isDiagnosedNonEscapable(getResultWithoutYield()) ||
1124+
isDiagnosedNonEscapable(getYields())) {
11071125
if (isInit() && isImplicitOrSIL()) {
11081126
inferImplicitInit();
11091127
} else if (hasImplicitSelfParam()) {
@@ -1211,7 +1229,8 @@ class LifetimeDependenceChecker {
12111229
// error.
12121230
std::optional<LifetimeDependenceKind>
12131231
getImplicitAccessorResultDependence(AccessorDecl *accessor) {
1214-
if (!isDiagnosedNonEscapable(getResultOrYield()))
1232+
if (!isDiagnosedNonEscapable(getResultWithoutYield()) &&
1233+
!isDiagnosedNonEscapable(getYields()))
12151234
return std::nullopt;
12161235

12171236
std::optional<AccessorKind> wrappedAccessorKind = std::nullopt;

0 commit comments

Comments
 (0)