@@ -2018,65 +2018,23 @@ synthesizeMainBody(AbstractFunctionDecl *fn, void *arg) {
20182018static FuncDecl *resolveMainFunctionDecl (DeclContext *declContext,
20192019 ResolvedMemberResult &resolution,
20202020 ASTContext &ctx) {
2021- // The normal resolution mechanism won't choose the asynchronous main function
2022- // unless no other options are available because extensions and generic types
2023- // (structs/classes) are not considered asynchronous contexts.
2024- // We want them to be promoted to a viable entrypoint if the deployment target
2025- // is high enough.
2026- SmallVector<FuncDecl *, 4 > viableCandidates;
2027- for (ValueDecl *candidate : resolution.getMemberDecls (Viable)) {
2028- if (FuncDecl *function = dyn_cast<FuncDecl>(candidate)) {
2029- if (function->isMainTypeMainMethod ())
2030- viableCandidates.push_back (function);
2021+ // Choose the best overload if it's a main function
2022+ if (resolution.hasBestOverload ()) {
2023+ ValueDecl *best = resolution.getBestOverload ();
2024+ if (FuncDecl *func = dyn_cast<FuncDecl>(best)) {
2025+ if (func->isMainTypeMainMethod ()) {
2026+ return func;
2027+ }
20312028 }
20322029 }
2033- if (viableCandidates.empty ()) {
2034- return nullptr ;
2035- }
2036-
2037- AvailabilityContext contextAvailability =
2038- AvailabilityContext::forDeploymentTarget (ctx);
2039- const bool hasAsyncSupport = contextAvailability.isContainedIn (
2040- ctx.getBackDeployedConcurrencyAvailability ());
2041-
2042- FuncDecl *best = nullptr ;
2043- for (FuncDecl *candidate : viableCandidates) {
2044- // The candidate will work if it's synchronous, or if we support concurrency
2045- // and it is async, or if we are in YOLO mode
2046- const bool candidateWorks = !candidate->hasAsync () ||
2047- (hasAsyncSupport && candidate->hasAsync ()) ||
2048- ctx.LangOpts .DisableAvailabilityChecking ;
2049-
2050- // Skip it if it won't work
2051- if (!candidateWorks)
2052- continue ;
2053-
2054- // If we don't have a best, the candidate is the best so far
2055- if (!best) {
2056- best = candidate;
2057- continue ;
2030+ // Look for the most highly-ranked main-function candidate
2031+ for (ValueDecl *candidate : resolution.getMemberDecls (Viable)) {
2032+ if (FuncDecl *func = dyn_cast<FuncDecl>(candidate)) {
2033+ if (func->isMainTypeMainMethod ())
2034+ return func;
20582035 }
2059-
2060- // If the candidate is better and it's synchronous, just swap it right in.
2061- // If the candidate is better and it's async, make sure we support async
2062- // before selecting it.
2063- //
2064- // If it's unordered (equally bestest), use the async version if we support
2065- // it or use the sync version if we don't.
2066- const Comparison rank =
2067- TypeChecker::compareDeclarations (declContext, candidate, best);
2068- const bool isBetter = rank == Comparison::Better;
2069- const bool isUnordered = rank == Comparison::Unordered;
2070- const bool swapForAsync =
2071- hasAsyncSupport && candidate->hasAsync () && !best->hasAsync ();
2072- const bool swapForSync =
2073- !hasAsyncSupport && !candidate->hasAsync () && best->hasAsync ();
2074- const bool selectCandidate =
2075- isBetter || (isUnordered && (swapForAsync || swapForSync));
2076- if (selectCandidate)
2077- best = candidate;
2078- }
2079- return best;
2036+ }
2037+ return nullptr ;
20802038}
20812039
20822040FuncDecl *
0 commit comments