mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Add a function for querying the isolation of an Initializer.
This commit is contained in:
@@ -28,6 +28,7 @@ class raw_ostream;
|
||||
|
||||
namespace swift {
|
||||
class DeclContext;
|
||||
class Initializer;
|
||||
class ModuleDecl;
|
||||
class VarDecl;
|
||||
class NominalTypeDecl;
|
||||
@@ -434,6 +435,10 @@ InferredActorIsolation getInferredActorIsolation(ValueDecl *value);
|
||||
ActorIsolation
|
||||
__AbstractClosureExpr_getActorIsolation(AbstractClosureExpr *CE);
|
||||
|
||||
/// Determine how the given initialization context is isolated.
|
||||
ActorIsolation getActorIsolation(Initializer *init,
|
||||
bool ignoreDefaultArguments = false);
|
||||
|
||||
/// Determine how the given declaration context is isolated.
|
||||
/// \p getClosureActorIsolation allows the specification of actor isolation for
|
||||
/// closures that haven't been saved been saved to the AST yet. This is useful
|
||||
|
||||
@@ -12076,7 +12076,6 @@ ActorIsolation swift::getActorIsolationOfContext(
|
||||
DeclContext *dc,
|
||||
llvm::function_ref<ActorIsolation(AbstractClosureExpr *)>
|
||||
getClosureActorIsolation) {
|
||||
auto &ctx = dc->getASTContext();
|
||||
auto dcToUse = dc;
|
||||
|
||||
// Defer bodies share the actor isolation of their enclosing context.
|
||||
@@ -12091,44 +12090,79 @@ ActorIsolation swift::getActorIsolationOfContext(
|
||||
if (auto *vd = dyn_cast_or_null<ValueDecl>(dcToUse->getAsDecl()))
|
||||
return getActorIsolation(vd);
|
||||
|
||||
// In the context of the initializing or default-value expression of a
|
||||
// stored property:
|
||||
// - For a static stored property, the isolation matches the VarDecl.
|
||||
// Static properties are initialized upon first use, so the isolation
|
||||
// of the initializer must match the isolation required to access the
|
||||
// property.
|
||||
// - For a field of a nominal type, the expression can require the same
|
||||
// actor isolation as the field itself. That default expression may only
|
||||
// be used from inits that meet the required isolation.
|
||||
if (auto *var = dcToUse->getNonLocalVarDecl()) {
|
||||
// If IsolatedDefaultValues are enabled, treat this context as having
|
||||
// unspecified isolation. We'll compute the required isolation for
|
||||
// the initializer and validate that it matches the isolation of the
|
||||
// var itself in the DefaultInitializerIsolation request.
|
||||
if (ctx.LangOpts.hasFeature(Feature::IsolatedDefaultValues))
|
||||
return ActorIsolation::forUnspecified();
|
||||
|
||||
return getActorIsolation(var);
|
||||
}
|
||||
|
||||
if (auto *closure = dyn_cast<AbstractClosureExpr>(dcToUse)) {
|
||||
return getClosureActorIsolation(closure);
|
||||
}
|
||||
|
||||
if (auto *init = dyn_cast<Initializer>(dcToUse)) {
|
||||
// FIXME: force default argument initializers to report a meaningless
|
||||
// isolation in order to break a bunch of cycles with the way that
|
||||
// isolation is computed for them.
|
||||
return getActorIsolation(init, /*ignoreDefaultArguments*/ true);
|
||||
}
|
||||
|
||||
if (isa<TopLevelCodeDecl>(dcToUse)) {
|
||||
auto &ctx = dc->getASTContext();
|
||||
if (dcToUse->isAsyncContext() ||
|
||||
dcToUse->getASTContext().LangOpts.StrictConcurrencyLevel >=
|
||||
StrictConcurrency::Complete) {
|
||||
if (Type mainActor = dcToUse->getASTContext().getMainActorType())
|
||||
ctx.LangOpts.StrictConcurrencyLevel >= StrictConcurrency::Complete) {
|
||||
if (Type mainActor = ctx.getMainActorType())
|
||||
return ActorIsolation::forGlobalActor(mainActor)
|
||||
.withPreconcurrency(
|
||||
!dcToUse->getASTContext().isSwiftVersionAtLeast(6));
|
||||
.withPreconcurrency(!ctx.isSwiftVersionAtLeast(6));
|
||||
}
|
||||
}
|
||||
|
||||
return ActorIsolation::forUnspecified();
|
||||
}
|
||||
|
||||
ActorIsolation swift::getActorIsolation(Initializer *init,
|
||||
bool ignoreDefaultArguments) {
|
||||
switch (init->getInitializerKind()) {
|
||||
case InitializerKind::PatternBinding:
|
||||
// In the context of the initializing or default-value expression of a
|
||||
// stored property:
|
||||
// - For a static stored property, the isolation matches the VarDecl.
|
||||
// Static properties are initialized upon first use, so the isolation
|
||||
// of the initializer must match the isolation required to access the
|
||||
// property.
|
||||
// - For a field of a nominal type, the expression can require the same
|
||||
// actor isolation as the field itself. That default expression may only
|
||||
// be used from inits that meet the required isolation.
|
||||
if (auto *var = init->getNonLocalVarDecl()) {
|
||||
auto &ctx = var->getASTContext();
|
||||
|
||||
// If IsolatedDefaultValues are enabled, treat this context as having
|
||||
// unspecified isolation. We'll compute the required isolation for
|
||||
// the initializer and validate that it matches the isolation of the
|
||||
// var itself in the DefaultInitializerIsolation request.
|
||||
if (ctx.LangOpts.hasFeature(Feature::IsolatedDefaultValues))
|
||||
return ActorIsolation::forUnspecified();
|
||||
|
||||
return getActorIsolation(var);
|
||||
}
|
||||
|
||||
return ActorIsolation::forUnspecified();
|
||||
|
||||
case InitializerKind::DefaultArgument: {
|
||||
auto defArgInit = cast<DefaultArgumentInitializer>(init);
|
||||
|
||||
// A hack when used from getActorIsolationOfContext to maintain the
|
||||
// current behavior and avoid request cycles.
|
||||
if (ignoreDefaultArguments)
|
||||
return ActorIsolation::forUnspecified();
|
||||
|
||||
auto fn = cast<ValueDecl>(defArgInit->getParent()->getAsDecl());
|
||||
auto param = getParameterAt(fn, defArgInit->getIndex());
|
||||
assert(param);
|
||||
return param->getInitializerIsolation();
|
||||
}
|
||||
|
||||
case InitializerKind::PropertyWrapper:
|
||||
case InitializerKind::CustomAttribute:
|
||||
return ActorIsolation::forUnspecified();
|
||||
}
|
||||
llvm_unreachable("bad initializer kind");
|
||||
}
|
||||
|
||||
bool swift::isSameActorIsolated(ValueDecl *value, DeclContext *dc) {
|
||||
auto valueIsolation = getActorIsolation(value);
|
||||
auto dcIsolation = getActorIsolationOfContext(dc);
|
||||
|
||||
Reference in New Issue
Block a user