mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Concurrency] Remove -executor-factory option and replace with magic type.
We decided that using a magic typealias to set the executor factory was better than using a compiler option. Remove the `-executor-factory` option, and replace by looking up the `DefaultExecutorFactory` type, first in the main module, and then if that fails in Concurrency. rdar://149058236
This commit is contained in:
@@ -1136,12 +1136,9 @@ NOTE(rbi_add_generic_parameter_sendable_conformance,none,
|
|||||||
|
|
||||||
// Concurrency related diagnostics
|
// Concurrency related diagnostics
|
||||||
ERROR(cannot_find_executor_factory_type, none,
|
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,
|
ERROR(executor_factory_must_conform, none,
|
||||||
"the executor factory '%0' does not conform to 'ExecutorFactory'",
|
"the DefaultExecutorFactory does not conform to 'ExecutorFactory'", ())
|
||||||
(StringRef))
|
|
||||||
ERROR(executor_factory_not_supported, none,
|
|
||||||
"deployment target too low for executor factory specification", ())
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// MARK: Misc Diagnostics
|
// MARK: Misc Diagnostics
|
||||||
|
|||||||
@@ -409,10 +409,6 @@ namespace swift {
|
|||||||
/// Specifies how strict concurrency checking will be.
|
/// Specifies how strict concurrency checking will be.
|
||||||
StrictConcurrency StrictConcurrencyLevel = StrictConcurrency::Minimal;
|
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.
|
/// Enable experimental concurrency model.
|
||||||
bool EnableExperimentalConcurrency = false;
|
bool EnableExperimentalConcurrency = false;
|
||||||
|
|
||||||
|
|||||||
@@ -998,16 +998,6 @@ def default_isolation_EQ : Joined<["-"], "default-isolation=">,
|
|||||||
Flags<[FrontendOption]>,
|
Flags<[FrontendOption]>,
|
||||||
Alias<default_isolation>;
|
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 :
|
def enable_experimental_feature :
|
||||||
Separate<["-"], "enable-experimental-feature">,
|
Separate<["-"], "enable-experimental-feature">,
|
||||||
Flags<[FrontendOption, ModuleInterfaceOption]>,
|
Flags<[FrontendOption, ModuleInterfaceOption]>,
|
||||||
|
|||||||
@@ -379,10 +379,6 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
|
|||||||
arguments.push_back(inputArgs.MakeArgString(globalRemapping));
|
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.
|
// Pass through the values passed to -Xfrontend.
|
||||||
inputArgs.AddAllArgValues(arguments, options::OPT_Xfrontend);
|
inputArgs.AddAllArgValues(arguments, options::OPT_Xfrontend);
|
||||||
|
|
||||||
|
|||||||
@@ -1364,12 +1364,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
|||||||
Opts.enableFeature(Feature::RegionBasedIsolation);
|
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 =
|
Opts.WarnImplicitOverrides =
|
||||||
Args.hasArg(OPT_warn_implicit_overrides);
|
Args.hasArg(OPT_warn_implicit_overrides);
|
||||||
|
|
||||||
|
|||||||
@@ -514,25 +514,14 @@ FuncDecl *SILGenModule::getExit() {
|
|||||||
Type SILGenModule::getConfiguredExecutorFactory() {
|
Type SILGenModule::getConfiguredExecutorFactory() {
|
||||||
auto &ctx = getASTContext();
|
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
|
// If we don't find it, fall back to _Concurrency.PlatformExecutorFactory
|
||||||
StringRef qualifiedName = *ctx.LangOpts.ExecutorFactory;
|
if (!factory)
|
||||||
StringRef typeName;
|
factory = getDefaultExecutorFactory();
|
||||||
|
|
||||||
auto parts = qualifiedName.split('.');
|
return factory;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type SILGenModule::getDefaultExecutorFactory() {
|
Type SILGenModule::getDefaultExecutorFactory() {
|
||||||
|
|||||||
@@ -1424,51 +1424,44 @@ void SILGenFunction::emitAsyncMainThreadStart(SILDeclRef entryPoint) {
|
|||||||
|
|
||||||
B.setInsertionPoint(entryBlock);
|
B.setInsertionPoint(entryBlock);
|
||||||
|
|
||||||
// If we're using a new enough deployment target, call swift_createExecutors()
|
// If we're using a new enough deployment target, and we can find a
|
||||||
if (ctx.LangOpts.ExecutorFactory) {
|
// DefaultExecutorFactory type, call swift_createExecutors()
|
||||||
if (!isCreateExecutorsFunctionAvailable(SGM)) {
|
Type factoryNonCanTy = SGM.getConfiguredExecutorFactory();
|
||||||
ctx.Diags.diagnose(SourceLoc(), diag::executor_factory_not_supported);
|
|
||||||
} else {
|
|
||||||
CanType factoryTy = SGM.getConfiguredExecutorFactory()->getCanonicalType();
|
|
||||||
|
|
||||||
if (!factoryTy) {
|
if (isCreateExecutorsFunctionAvailable(SGM) && factoryNonCanTy) {
|
||||||
ctx.Diags.diagnose(SourceLoc(), diag::cannot_find_executor_factory_type,
|
CanType factoryTy = factoryNonCanTy->getCanonicalType();
|
||||||
*ctx.LangOpts.ExecutorFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProtocolDecl *executorFactoryProtocol
|
ProtocolDecl *executorFactoryProtocol
|
||||||
= ctx.getProtocol(KnownProtocolKind::ExecutorFactory);
|
= ctx.getProtocol(KnownProtocolKind::ExecutorFactory);
|
||||||
auto conformance = lookupConformance(factoryTy, executorFactoryProtocol);
|
auto conformance = lookupConformance(factoryTy, executorFactoryProtocol);
|
||||||
|
|
||||||
if (conformance.isInvalid()) {
|
if (conformance.isInvalid()) {
|
||||||
// If this type doesn't conform, ignore it and use the default factory
|
// If this type doesn't conform, ignore it and use the default factory
|
||||||
SourceLoc loc = extractNearestSourceLoc(factoryTy);
|
SourceLoc loc = extractNearestSourceLoc(factoryTy);
|
||||||
|
|
||||||
ctx.Diags.diagnose(loc, diag::executor_factory_must_conform,
|
ctx.Diags.diagnose(loc, diag::executor_factory_must_conform);
|
||||||
*ctx.LangOpts.ExecutorFactory);
|
|
||||||
|
|
||||||
factoryTy = SGM.getDefaultExecutorFactory()->getCanonicalType();
|
factoryTy = SGM.getDefaultExecutorFactory()->getCanonicalType();
|
||||||
conformance = lookupConformance(factoryTy, executorFactoryProtocol);
|
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),
|
|
||||||
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 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 });
|
||||||
}
|
}
|
||||||
|
|
||||||
auto wrapCallArgs = [this, &moduleLoc](SILValue originalValue, FuncDecl *fd,
|
auto wrapCallArgs = [this, &moduleLoc](SILValue originalValue, FuncDecl *fd,
|
||||||
|
|||||||
@@ -534,6 +534,9 @@ public protocol ExecutorFactory {
|
|||||||
static var defaultExecutor: any TaskExecutor { get }
|
static var defaultExecutor: any TaskExecutor { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(SwiftStdlib 6.2, *)
|
||||||
|
typealias DefaultExecutorFactory = PlatformExecutorFactory
|
||||||
|
|
||||||
@available(SwiftStdlib 6.2, *)
|
@available(SwiftStdlib 6.2, *)
|
||||||
@_silgen_name("swift_createExecutors")
|
@_silgen_name("swift_createExecutors")
|
||||||
public func _createExecutors<F: ExecutorFactory>(factory: F.Type) {
|
public func _createExecutors<F: ExecutorFactory>(factory: F.Type) {
|
||||||
@@ -556,7 +559,7 @@ extension MainActor {
|
|||||||
@available(SwiftStdlib 6.2, *)
|
@available(SwiftStdlib 6.2, *)
|
||||||
public static var executor: any MainExecutor {
|
public static var executor: any MainExecutor {
|
||||||
if _executor == nil {
|
if _executor == nil {
|
||||||
_executor = PlatformExecutorFactory.mainExecutor
|
_executor = DefaultExecutorFactory.mainExecutor
|
||||||
}
|
}
|
||||||
return _executor!
|
return _executor!
|
||||||
}
|
}
|
||||||
@@ -575,7 +578,7 @@ extension Task where Success == Never, Failure == Never {
|
|||||||
@available(SwiftStdlib 6.2, *)
|
@available(SwiftStdlib 6.2, *)
|
||||||
public static var defaultExecutor: any TaskExecutor {
|
public static var defaultExecutor: any TaskExecutor {
|
||||||
if _defaultExecutor == nil {
|
if _defaultExecutor == nil {
|
||||||
_defaultExecutor = PlatformExecutorFactory.defaultExecutor
|
_defaultExecutor = DefaultExecutorFactory.defaultExecutor
|
||||||
}
|
}
|
||||||
return _defaultExecutor!
|
return _defaultExecutor!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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: concurrency
|
||||||
// REQUIRES: executable_test
|
// REQUIRES: executable_test
|
||||||
@@ -13,6 +13,8 @@
|
|||||||
import StdlibUnittest
|
import StdlibUnittest
|
||||||
import Synchronization
|
import Synchronization
|
||||||
|
|
||||||
|
typealias DefaultExecutorFactory = SimpleExecutorFactory
|
||||||
|
|
||||||
struct SimpleExecutorFactory: ExecutorFactory {
|
struct SimpleExecutorFactory: ExecutorFactory {
|
||||||
public static var mainExecutor: any MainExecutor {
|
public static var mainExecutor: any MainExecutor {
|
||||||
print("Creating main executor")
|
print("Creating main executor")
|
||||||
|
|||||||
Reference in New Issue
Block a user