Skip to content

[Concurrency] Remove -executor-factory option and replace with magic type. #80795

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: release/6.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -1136,12 +1136,9 @@ NOTE(rbi_add_generic_parameter_sendable_conformance,none,

// Concurrency related diagnostics
ERROR(cannot_find_executor_factory_type, none,
"the specified executor factory '%0' could not be found", (StringRef))
"the DefaultExecutorFactory type could not be found", ())
ERROR(executor_factory_must_conform, none,
"the executor factory '%0' does not conform to 'ExecutorFactory'",
(StringRef))
ERROR(executor_factory_not_supported, none,
"deployment target too low for executor factory specification", ())
"the DefaultExecutorFactory does not conform to 'ExecutorFactory'", ())

//===----------------------------------------------------------------------===//
// MARK: Misc Diagnostics
Expand Down
4 changes: 0 additions & 4 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,6 @@ namespace swift {
/// Specifies how strict concurrency checking will be.
StrictConcurrency StrictConcurrencyLevel = StrictConcurrency::Minimal;

/// Specifies the name of the executor factory to use to create the
/// default executors for Swift Concurrency.
std::optional<std::string> ExecutorFactory;

/// Enable experimental concurrency model.
bool EnableExperimentalConcurrency = false;

Expand Down
10 changes: 0 additions & 10 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -998,16 +998,6 @@ def default_isolation_EQ : Joined<["-"], "default-isolation=">,
Flags<[FrontendOption]>,
Alias<default_isolation>;

def executor_factory : JoinedOrSeparate<["-"], "executor-factory">,
Flags<[FrontendOption]>,
HelpText<"Specify the factory to use to create the default executors for "
"Swift Concurrency. This must be a type conforming to the "
"'ExecutorFactory' protocol.">,
MetaVarName<"<factory-type>">;
def executor_factory_EQ : Joined<["-"], "executor-factory=">,
Flags<[FrontendOption]>,
Alias<executor_factory>;

def enable_experimental_feature :
Separate<["-"], "enable-experimental-feature">,
Flags<[FrontendOption, ModuleInterfaceOption]>,
Expand Down
4 changes: 0 additions & 4 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,6 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
arguments.push_back(inputArgs.MakeArgString(globalRemapping));
}

if (inputArgs.hasArg(options::OPT_executor_factory)) {
inputArgs.AddLastArg(arguments, options::OPT_executor_factory);
}

// Pass through the values passed to -Xfrontend.
inputArgs.AddAllArgValues(arguments, options::OPT_Xfrontend);

Expand Down
6 changes: 0 additions & 6 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1364,12 +1364,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.enableFeature(Feature::RegionBasedIsolation);
}

// Get the executor factory name
if (const Arg *A = Args.getLastArg(OPT_executor_factory)) {
printf("Got executor-factory option\n");
Opts.ExecutorFactory = A->getValue();
}

Opts.WarnImplicitOverrides =
Args.hasArg(OPT_warn_implicit_overrides);

Expand Down
23 changes: 6 additions & 17 deletions lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,25 +514,14 @@ FuncDecl *SILGenModule::getExit() {
Type SILGenModule::getConfiguredExecutorFactory() {
auto &ctx = getASTContext();

ModuleDecl *module;
// Look in the main module for a typealias
Type factory = ctx.getNamedSwiftType(ctx.MainModule, "DefaultExecutorFactory");

// Parse the executor factory name
StringRef qualifiedName = *ctx.LangOpts.ExecutorFactory;
StringRef typeName;
// If we don't find it, fall back to _Concurrency.PlatformExecutorFactory
if (!factory)
factory = getDefaultExecutorFactory();

auto parts = qualifiedName.split('.');

if (parts.second.empty()) {
// This was an unqualified name; assume it's relative to the main module
module = ctx.MainModule;
typeName = qualifiedName;
} else {
Identifier moduleName = ctx.getIdentifier(parts.first);
module = ctx.getModuleByIdentifier(moduleName);
typeName = parts.second;
}

return ctx.getNamedSwiftType(module, typeName);
return factory;
}

Type SILGenModule::getDefaultExecutorFactory() {
Expand Down
67 changes: 30 additions & 37 deletions lib/SILGen/SILGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1424,51 +1424,44 @@ void SILGenFunction::emitAsyncMainThreadStart(SILDeclRef entryPoint) {

B.setInsertionPoint(entryBlock);

// If we're using a new enough deployment target, call swift_createExecutors()
if (ctx.LangOpts.ExecutorFactory) {
if (!isCreateExecutorsFunctionAvailable(SGM)) {
ctx.Diags.diagnose(SourceLoc(), diag::executor_factory_not_supported);
} else {
CanType factoryTy = SGM.getConfiguredExecutorFactory()->getCanonicalType();
// If we're using a new enough deployment target, and we can find a
// DefaultExecutorFactory type, call swift_createExecutors()
Type factoryNonCanTy = SGM.getConfiguredExecutorFactory();

if (!factoryTy) {
ctx.Diags.diagnose(SourceLoc(), diag::cannot_find_executor_factory_type,
*ctx.LangOpts.ExecutorFactory);
}
if (isCreateExecutorsFunctionAvailable(SGM) && factoryNonCanTy) {
CanType factoryTy = factoryNonCanTy->getCanonicalType();

ProtocolDecl *executorFactoryProtocol
= ctx.getProtocol(KnownProtocolKind::ExecutorFactory);
auto conformance = lookupConformance(factoryTy, executorFactoryProtocol);
ProtocolDecl *executorFactoryProtocol
= ctx.getProtocol(KnownProtocolKind::ExecutorFactory);
auto conformance = lookupConformance(factoryTy, executorFactoryProtocol);

if (conformance.isInvalid()) {
// If this type doesn't conform, ignore it and use the default factory
SourceLoc loc = extractNearestSourceLoc(factoryTy);
if (conformance.isInvalid()) {
// If this type doesn't conform, ignore it and use the default factory
SourceLoc loc = extractNearestSourceLoc(factoryTy);

ctx.Diags.diagnose(loc, diag::executor_factory_must_conform,
*ctx.LangOpts.ExecutorFactory);
ctx.Diags.diagnose(loc, diag::executor_factory_must_conform);

factoryTy = SGM.getDefaultExecutorFactory()->getCanonicalType();
conformance = lookupConformance(factoryTy, executorFactoryProtocol);
factoryTy = SGM.getDefaultExecutorFactory()->getCanonicalType();
conformance = lookupConformance(factoryTy, executorFactoryProtocol);

assert(!conformance.isInvalid());
}
assert(!conformance.isInvalid());
}

FuncDecl *createExecutorsFuncDecl = SGM.getCreateExecutors();
assert(createExecutorsFuncDecl
&& "Failed to find swift_createExecutors function decl");
SILFunction *createExecutorsSILFunc =
SGM.getFunction(SILDeclRef(createExecutorsFuncDecl, SILDeclRef::Kind::Func),
FuncDecl *createExecutorsFuncDecl = SGM.getCreateExecutors();
assert(createExecutorsFuncDecl
&& "Failed to find swift_createExecutors function decl");
SILFunction *createExecutorsSILFunc =
SGM.getFunction(SILDeclRef(createExecutorsFuncDecl, SILDeclRef::Kind::Func),
NotForDefinition);
SILValue createExecutorsFunc =
B.createFunctionRefFor(moduleLoc, createExecutorsSILFunc);
MetatypeType *factoryThickMetaTy
= MetatypeType::get(factoryTy, MetatypeRepresentation::Thick);
SILValue factorySILMetaTy
= B.createMetatype(moduleLoc, getLoweredType(factoryThickMetaTy));
auto ceSubs = SubstitutionMap::getProtocolSubstitutions(
conformance.getProtocol(), factoryTy, conformance);
B.createApply(moduleLoc, createExecutorsFunc, ceSubs, { factorySILMetaTy });
}
SILValue createExecutorsFunc =
B.createFunctionRefFor(moduleLoc, createExecutorsSILFunc);
MetatypeType *factoryThickMetaTy
= MetatypeType::get(factoryTy, MetatypeRepresentation::Thick);
SILValue factorySILMetaTy
= B.createMetatype(moduleLoc, getLoweredType(factoryThickMetaTy));
auto ceSubs = SubstitutionMap::getProtocolSubstitutions(
conformance.getProtocol(), factoryTy, conformance);
B.createApply(moduleLoc, createExecutorsFunc, ceSubs, { factorySILMetaTy });
}

auto wrapCallArgs = [this, &moduleLoc](SILValue originalValue, FuncDecl *fd,
Expand Down
7 changes: 5 additions & 2 deletions stdlib/public/Concurrency/Executor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,9 @@ public protocol ExecutorFactory {
static var defaultExecutor: any TaskExecutor { get }
}

@available(SwiftStdlib 6.2, *)
typealias DefaultExecutorFactory = PlatformExecutorFactory

@available(SwiftStdlib 6.2, *)
@_silgen_name("swift_createExecutors")
public func _createExecutors<F: ExecutorFactory>(factory: F.Type) {
Expand All @@ -556,7 +559,7 @@ extension MainActor {
@available(SwiftStdlib 6.2, *)
public static var executor: any MainExecutor {
if _executor == nil {
_executor = PlatformExecutorFactory.mainExecutor
_executor = DefaultExecutorFactory.mainExecutor
}
return _executor!
}
Expand All @@ -575,7 +578,7 @@ extension Task where Success == Never, Failure == Never {
@available(SwiftStdlib 6.2, *)
public static var defaultExecutor: any TaskExecutor {
if _defaultExecutor == nil {
_defaultExecutor = PlatformExecutorFactory.defaultExecutor
_defaultExecutor = DefaultExecutorFactory.defaultExecutor
}
return _defaultExecutor!
}
Expand Down
4 changes: 3 additions & 1 deletion test/Concurrency/Runtime/custom_main_executor.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -g %import-libdispatch -parse-as-library -executor-factory SimpleExecutorFactory) | %FileCheck %s
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -g %import-libdispatch -parse-as-library) | %FileCheck %s

// REQUIRES: concurrency
// REQUIRES: executable_test
Expand All @@ -13,6 +13,8 @@
import StdlibUnittest
import Synchronization

typealias DefaultExecutorFactory = SimpleExecutorFactory

struct SimpleExecutorFactory: ExecutorFactory {
public static var mainExecutor: any MainExecutor {
print("Creating main executor")
Expand Down