@@ -2018,65 +2018,23 @@ synthesizeMainBody(AbstractFunctionDecl *fn, void *arg) {
2018
2018
static FuncDecl *resolveMainFunctionDecl (DeclContext *declContext,
2019
2019
ResolvedMemberResult &resolution,
2020
2020
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
+ }
2031
2028
}
2032
2029
}
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;
2058
2035
}
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 ;
2080
2038
}
2081
2039
2082
2040
FuncDecl *
0 commit comments