@@ -696,19 +696,6 @@ void TypeChecker::checkDistributedActor(SourceFile *SF, NominalTypeDecl *nominal
696696 // If applicable, this will create the default 'init(transport:)' initializer
697697 (void )nominal->getDefaultInitializer ();
698698
699- // We check decls for ambiguity more strictly than normal nominal types,
700- // because we want to record distributed accessors the same if function they
701- // point at (in a remote process) is async or not, as that has no effect on
702- // a caller from a different process, so we want to make the remoteCall target
703- // identifiers, less fragile against such refactorings.
704- //
705- // To achieve this, we ban overloads on just "effects" of functions,
706- // which are useful in local settings, but really should not be relied
707- // on as differenciators in remote calls - the call will always be "async"
708- // since it will go through a thunk, and then be asynchronously transferred
709- // to the called process.
710- llvm::SmallDenseSet<DeclName, 2 > diagnosedAmbiguity;
711-
712699 for (auto member : nominal->getMembers ()) {
713700 // --- Ensure 'distributed func' all thunks
714701 if (auto *var = dyn_cast<VarDecl>(member)) {
@@ -734,48 +721,6 @@ void TypeChecker::checkDistributedActor(SourceFile *SF, NominalTypeDecl *nominal
734721 nominal->getName ());
735722 return ;
736723 }
737-
738- // Check there's no async/no-async overloads, since those are more
739- // fragile in distribution than we'd want distributed calls to be.
740- // A remote call is always 'async throws', and we can always record
741- // an async throws "accessor" (see AccessibleFunction.cpp) as such.
742- // This means, if we allowed async/no-async overloads of functions,
743- // we'd have to store the precise "it was not throwing" information,
744- // but we'll _never_ make use of such because all remote calls are
745- // necessarily going to async to the actor in the recipient process,
746- // and for the remote caller, they are always as-if-async.
747- //
748- // By banning such overloads, which may be useful in local APIs,
749- // but too fragile in distributed APIs, we allow a remote 'v2' version
750- // of an implementation to add or remove `async` to their implementation
751- // without breaking calls which were made on previous 'v1' versions of
752- // the same interface; Callers are never broken this way, and rollouts
753- // are simpler.
754- //
755- // The restriction on overloads is not a problem for distributed calls,
756- // as we don't have a vast swab of APIs which must compatibly get async
757- // versions, as that is what the async overloading aimed to address.
758- //
759- // Note also, that overloading on throws is already illegal anyway.
760- if (!diagnosedAmbiguity.contains (func->getName ())) {
761- auto candidates = nominal->lookupDirect (func->getName ());
762- if (candidates.size () > 1 ) {
763- auto firstDecl = dyn_cast<AbstractFunctionDecl>(candidates.back ());
764- for (auto decl : candidates) {
765- if (decl == firstDecl) {
766- decl->diagnose (
767- diag::distributed_func_cannot_overload_on_async_only,
768- decl->getName ());
769- } else {
770- decl->diagnose (
771- diag::distributed_func_other_ambiguous_overload_here,
772- decl->getName ());
773- }
774- }
775-
776- diagnosedAmbiguity.insert (func->getName ());
777- }
778- }
779724 }
780725
781726 if (auto thunk = func->getDistributedThunk ()) {
0 commit comments