mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Fix SILGen's computation of default argument generator isolation
This commit is contained in:
@@ -38,6 +38,7 @@ namespace swift {
|
||||
enum class EffectsKind : uint8_t;
|
||||
class AbstractFunctionDecl;
|
||||
class AbstractClosureExpr;
|
||||
class ActorIsolation;
|
||||
class ValueDecl;
|
||||
class FuncDecl;
|
||||
class ClosureExpr;
|
||||
@@ -498,6 +499,8 @@ struct SILDeclRef {
|
||||
return result;
|
||||
}
|
||||
|
||||
ActorIsolation getActorIsolation() const;
|
||||
|
||||
/// True if the decl ref references a thunk from a natively foreign
|
||||
/// declaration to Swift calling convention.
|
||||
bool isForeignToNativeThunk() const;
|
||||
|
||||
@@ -1873,3 +1873,21 @@ bool SILDeclRef::isCalleeAllocatedCoroutine() const {
|
||||
|
||||
return getASTContext().SILOpts.CoroutineAccessorsUseYieldOnce2;
|
||||
}
|
||||
|
||||
ActorIsolation SILDeclRef::getActorIsolation() const {
|
||||
// Deallocating destructor is always nonisolated. Isolation of the deinit
|
||||
// applies only to isolated deallocator and destroyer.
|
||||
if (kind == SILDeclRef::Kind::Deallocator) {
|
||||
return ActorIsolation::forNonisolated(false);
|
||||
}
|
||||
|
||||
// Default argument generators use the isolation of the initializer,
|
||||
// not the general isolation of the function.
|
||||
if (isDefaultArgGenerator()) {
|
||||
auto param = getParameterAt(getDecl(), defaultArgIndex);
|
||||
assert(param);
|
||||
return param->getInitializerIsolation();
|
||||
}
|
||||
|
||||
return getActorIsolationOfContext(getInnermostDeclContext());
|
||||
}
|
||||
|
||||
@@ -2419,32 +2419,7 @@ swift::getSILFunctionTypeActorIsolation(CanAnyFunctionType substFnInterfaceType,
|
||||
}
|
||||
|
||||
if (constant) {
|
||||
// TODO: It should to be possible to `getActorIsolation` if
|
||||
// reference is to a decl instead of trying to get isolation
|
||||
// from the reference kind, the attributes, or the context.
|
||||
|
||||
if (constant->kind == SILDeclRef::Kind::Deallocator) {
|
||||
return ActorIsolation::forNonisolated(false);
|
||||
}
|
||||
|
||||
if (auto *decl = constant->getAbstractFunctionDecl()) {
|
||||
if (auto *nonisolatedAttr =
|
||||
decl->getAttrs().getAttribute<NonisolatedAttr>()) {
|
||||
if (nonisolatedAttr->isNonSending())
|
||||
return ActorIsolation::forCallerIsolationInheriting();
|
||||
}
|
||||
|
||||
if (decl->getAttrs().hasAttribute<ConcurrentAttr>()) {
|
||||
return ActorIsolation::forNonisolated(false /*unsafe*/);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto *closure = constant->getAbstractClosureExpr()) {
|
||||
if (auto isolation = closure->getActorIsolation())
|
||||
return isolation;
|
||||
}
|
||||
|
||||
return getActorIsolationOfContext(constant->getInnermostDeclContext());
|
||||
return constant->getActorIsolation();
|
||||
}
|
||||
|
||||
if (substFnInterfaceType->hasExtInfo() &&
|
||||
|
||||
@@ -768,32 +768,6 @@ static bool isEmittedOnDemand(SILModule &M, SILDeclRef constant) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static ActorIsolation getActorIsolationForFunction(SILFunction &fn) {
|
||||
if (auto constant = fn.getDeclRef()) {
|
||||
if (constant.kind == SILDeclRef::Kind::Deallocator) {
|
||||
// Deallocating destructor is always nonisolated. Isolation of the deinit
|
||||
// applies only to isolated deallocator and destroyer.
|
||||
return ActorIsolation::forNonisolated(false);
|
||||
}
|
||||
|
||||
// If we have a closure expr, check if our type is
|
||||
// nonisolated(nonsending). In that case, we use that instead.
|
||||
if (auto *closureExpr = constant.getAbstractClosureExpr()) {
|
||||
if (auto actorIsolation = closureExpr->getActorIsolation())
|
||||
return actorIsolation;
|
||||
}
|
||||
|
||||
// If we have actor isolation for our constant, put the isolation onto the
|
||||
// function. If the isolation is unspecified, we do not return it.
|
||||
if (auto isolation =
|
||||
getActorIsolationOfContext(constant.getInnermostDeclContext()))
|
||||
return isolation;
|
||||
}
|
||||
|
||||
// Otherwise, return for unspecified.
|
||||
return ActorIsolation::forUnspecified();
|
||||
}
|
||||
|
||||
SILFunction *SILGenModule::getFunction(SILDeclRef constant,
|
||||
ForDefinition_t forDefinition) {
|
||||
// If we already emitted the function, return it.
|
||||
@@ -820,7 +794,7 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant,
|
||||
});
|
||||
|
||||
F->setDeclRef(constant);
|
||||
F->setActorIsolation(getActorIsolationForFunction(*F));
|
||||
F->setActorIsolation(constant.getActorIsolation());
|
||||
|
||||
assert(F && "SILFunction should have been defined");
|
||||
|
||||
@@ -1316,7 +1290,7 @@ void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
|
||||
F->setDeclRef(constant);
|
||||
|
||||
// Set our actor isolation.
|
||||
F->setActorIsolation(getActorIsolationForFunction(*F));
|
||||
F->setActorIsolation(constant.getActorIsolation());
|
||||
|
||||
LLVM_DEBUG(llvm::dbgs() << "lowering ";
|
||||
F->printName(llvm::dbgs());
|
||||
|
||||
Reference in New Issue
Block a user