Skip to content

Commit f7e01fb

Browse files
committed
[TypeChecker] Allow missing requirements on Res generic parameter of DistributedActorSystem.remoteCall
Conformance requirement between on `Res` and `SerializationRequirement` of `DistributedActorSystem.remoteCall` are not expressible at the moment but they are verified by Sema so it's okay to omit them here and lookup dynamically during IRGen.
1 parent e59727a commit f7e01fb

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,13 +1237,52 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
12371237
}
12381238
bool requiresNonSendable = false;
12391239
if (!solution || solution->Fixes.size()) {
1240-
/// If the *only* problems are that `@Sendable` attributes are missing,
1241-
/// allow the match in some circumstances.
1242-
requiresNonSendable = solution
1243-
&& llvm::all_of(solution->Fixes, [](constraints::ConstraintFix *fix) {
1244-
return fix->getKind() == constraints::FixKind::AddSendableAttribute;
1245-
});
1246-
if (!requiresNonSendable)
1240+
auto isMatchedAllowed = [&](const constraints::Solution &solution) {
1241+
/// If the *only* problems are that `@Sendable` attributes are missing,
1242+
/// allow the match in some circumstances.
1243+
if (llvm::all_of(solution.Fixes, [](constraints::ConstraintFix *fix) {
1244+
return fix->getKind() ==
1245+
constraints::FixKind::AddSendableAttribute;
1246+
}))
1247+
return true;
1248+
1249+
auto *funcDecl = dyn_cast<AbstractFunctionDecl>(req);
1250+
// Conformance requirement between on `Res` and `SerializationRequirement`
1251+
// of `DistributedActorSystem.remoteCall` are not expressible at the moment
1252+
// but they are verified by Sema so it's okay to omit them here and lookup
1253+
// dynamically during IRGen.
1254+
if (funcDecl && funcDecl->isDistributedActorSystemRemoteCallRequirement(
1255+
/*withResult=*/true)) {
1256+
if (llvm::all_of(solution.Fixes, [&witness](constraints::ConstraintFix
1257+
*fix) {
1258+
auto conformance = dyn_cast<MissingConformance>(fix);
1259+
if (!conformance)
1260+
return false;
1261+
1262+
auto *locator = fix->getLocator();
1263+
auto requirement = locator->getLastElementAs<
1264+
LocatorPathElt::TypeParameterRequirement>();
1265+
if (!requirement)
1266+
return false;
1267+
1268+
auto signature =
1269+
locator->findLast<LocatorPathElt::OpenedGeneric>()
1270+
->getSignature();
1271+
1272+
auto subject =
1273+
signature.getRequirements()[requirement->getIndex()]
1274+
.getFirstType();
1275+
// `Res` is the result type so we can check against that.
1276+
return subject->isEqual(
1277+
cast<FuncDecl>(witness)->getResultInterfaceType());
1278+
}))
1279+
return true;
1280+
}
1281+
// In all other cases - disallow the match.
1282+
return false;
1283+
};
1284+
1285+
if (!solution || !isMatchedAllowed(*solution))
12471286
return RequirementMatch(witness, MatchKind::TypeConflict,
12481287
witnessType);
12491288
}

0 commit comments

Comments
 (0)