Merge pull request #69595 from ktoso/wip-distributed-overloads

[Distributed] Allow overloads with different types; mangling can handle it
This commit is contained in:
swift-ci
2023-11-06 03:31:44 -08:00
committed by GitHub
7 changed files with 144 additions and 75 deletions

View File

@@ -3203,9 +3203,37 @@ bool swift::conflicting(const OverloadSignature& sig1,
if (sig1.IsInstanceMember != sig2.IsInstanceMember)
return false;
// If one is an async function and the other is not, they can't conflict.
if (sig1.IsAsyncFunction != sig2.IsAsyncFunction)
return false;
// For distributed decls, check there's no async/no-async overloads,
// since those are more fragile in distribution than we'd want distributed calls to be.
//
// A remote call is always 'async throws', and we can always record
// an async throws "accessor" (see AccessibleFunction.cpp) as such.
// This means, if we allowed async/no-async overloads of functions,
// we'd have to store the precise "it was not throwing" information,
// but we'll _never_ make use of such because all remote calls are
// necessarily going to async to the actor in the recipient process,
// and for the remote caller, they are always as-if-async.
//
// By banning such overloads, which may be useful in local APIs,
// but too fragile in distributed APIs, we allow a remote 'v2' version
// of an implementation to add or remove `async` to their implementation
// without breaking calls which were made on previous 'v1' versions of
// the same interface; Callers are never broken this way, and rollouts
// are simpler.
//
// The restriction on overloads is not a problem for distributed calls,
// as we don't have a vast swab of APIs which must compatibly get async
// versions, as that is what the async overloading aimed to address.
//
// Note also, that overloading on throws is already illegal anyway.
if (sig1.IsDistributed || sig2.IsDistributed) {
if (sig1.IsAsyncFunction != sig2.IsAsyncFunction)
return true;
} else {
// Otherwise one is an async function and the other is not, they don't conflict.
if (sig1.IsAsyncFunction != sig2.IsAsyncFunction)
return false;
}
// If one is a macro and the other is not, they can't conflict.
if (sig1.IsMacro != sig2.IsMacro)
@@ -3458,6 +3486,8 @@ OverloadSignature ValueDecl::getOverloadSignature() const {
signature.IsFunction = true;
if (func->hasAsync())
signature.IsAsyncFunction = true;
if (func->isDistributed())
signature.IsDistributed = true;
}
if (auto *extension = dyn_cast<ExtensionDecl>(getDeclContext()))