Skip to content

Commit d3145b2

Browse files
committed
[silgen] Begin placing isolation on protocol witness thunks.
This will cause tests today to crash since even though we are placing the isolation now, to make it easier to read, I left in the old isolation selecting code. This code uses the witness's isolation instead of the requirement's isolation which is incorrect since the protocol witness thunk needs to look the requirement from an ABI perspective since the two must be substitutable. The crash comes from the ABI verification I added in earlier commits. (cherry picked from commit ff1cbea)
1 parent 3e66f88 commit d3145b2

File tree

3 files changed

+59
-33
lines changed

3 files changed

+59
-33
lines changed

include/swift/SIL/TypeLowering.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,14 @@ CanSILFunctionType getNativeSILFunctionType(
13891389
std::optional<SubstitutionMap> reqtSubs = std::nullopt,
13901390
ProtocolConformanceRef witnessMethodConformance = ProtocolConformanceRef());
13911391

1392+
/// origConstant is the parent decl ref in the case of class methods and the
1393+
/// witness method decl ref if we are working with a protocol witness. Pass in
1394+
/// None otherwise.
1395+
std::optional<ActorIsolation>
1396+
getSILFunctionTypeActorIsolation(CanAnyFunctionType substFnInterfaceType,
1397+
std::optional<SILDeclRef> origConstant,
1398+
std::optional<SILDeclRef> constant);
1399+
13921400
/// The thunk kinds used in the differentiation transform.
13931401
enum class DifferentiationThunkKind {
13941402
/// A reabstraction thunk.

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,6 +2391,49 @@ static void destructureYieldsForCoroutine(TypeConverter &TC,
23912391
}
23922392
}
23932393

2394+
std::optional<ActorIsolation>
2395+
swift::getSILFunctionTypeActorIsolation(CanAnyFunctionType substFnInterfaceType,
2396+
std::optional<SILDeclRef> origConstant,
2397+
std::optional<SILDeclRef> constant) {
2398+
if (constant) {
2399+
// TODO: It should to be possible to `getActorIsolation` if
2400+
// reference is to a decl instead of trying to get isolation
2401+
// from the reference kind, the attributes, or the context.
2402+
2403+
if (constant->kind == SILDeclRef::Kind::Deallocator) {
2404+
return ActorIsolation::forNonisolated(false);
2405+
}
2406+
2407+
if (auto *decl = constant->getAbstractFunctionDecl()) {
2408+
if (auto *nonisolatedAttr =
2409+
decl->getAttrs().getAttribute<NonisolatedAttr>()) {
2410+
if (nonisolatedAttr->isNonSending())
2411+
return ActorIsolation::forCallerIsolationInheriting();
2412+
}
2413+
2414+
if (decl->getAttrs().hasAttribute<ConcurrentAttr>()) {
2415+
return ActorIsolation::forNonisolated(false /*unsafe*/);
2416+
}
2417+
}
2418+
2419+
if (auto *closure = constant->getAbstractClosureExpr()) {
2420+
if (auto isolation = closure->getActorIsolation())
2421+
return isolation;
2422+
}
2423+
2424+
return getActorIsolationOfContext(constant->getInnermostDeclContext());
2425+
}
2426+
2427+
if (substFnInterfaceType->hasExtInfo() &&
2428+
substFnInterfaceType->getExtInfo().getIsolation().isNonIsolatedCaller()) {
2429+
// If our function type is a nonisolated caller and we can not infer from
2430+
// our constant, we must be caller isolation inheriting.
2431+
return ActorIsolation::forCallerIsolationInheriting();
2432+
}
2433+
2434+
return {};
2435+
}
2436+
23942437
/// Create the appropriate SIL function type for the given formal type
23952438
/// and conventions.
23962439
///
@@ -2622,39 +2665,8 @@ static CanSILFunctionType getSILFunctionType(
26222665
SmallBitVector addressableParams;
26232666
SmallBitVector conditionallyAddressableParams;
26242667
{
2625-
std::optional<ActorIsolation> actorIsolation;
2626-
if (constant) {
2627-
// TODO: It should to be possible to `getActorIsolation` if
2628-
// reference is to a decl instead of trying to get isolation
2629-
// from the reference kind, the attributes, or the context.
2630-
2631-
if (constant->kind == SILDeclRef::Kind::Deallocator) {
2632-
actorIsolation = ActorIsolation::forNonisolated(false);
2633-
} else if (auto *decl = constant->getAbstractFunctionDecl()) {
2634-
if (auto *nonisolatedAttr =
2635-
decl->getAttrs().getAttribute<NonisolatedAttr>()) {
2636-
if (nonisolatedAttr->isNonSending())
2637-
actorIsolation = ActorIsolation::forCallerIsolationInheriting();
2638-
} else if (decl->getAttrs().hasAttribute<ConcurrentAttr>()) {
2639-
actorIsolation = ActorIsolation::forNonisolated(false /*unsafe*/);
2640-
}
2641-
} else if (auto *closure = constant->getAbstractClosureExpr()) {
2642-
if (auto isolation = closure->getActorIsolation())
2643-
actorIsolation = isolation;
2644-
}
2645-
2646-
if (!actorIsolation) {
2647-
actorIsolation =
2648-
getActorIsolationOfContext(constant->getInnermostDeclContext());
2649-
}
2650-
} else if (substFnInterfaceType->hasExtInfo() &&
2651-
substFnInterfaceType->getExtInfo()
2652-
.getIsolation()
2653-
.isNonIsolatedCaller()) {
2654-
// If our function type is a nonisolated caller and we can not infer from
2655-
// our constant, we must be caller isolation inheriting.
2656-
actorIsolation = ActorIsolation::forCallerIsolationInheriting();
2657-
}
2668+
auto actorIsolation = getSILFunctionTypeActorIsolation(
2669+
substFnInterfaceType, origConstant, constant);
26582670
DestructureInputs destructurer(expansionContext, TC, conventions,
26592671
foreignInfo, actorIsolation, inputs,
26602672
parameterMap,

lib/SILGen/SILGenType.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,12 @@ SILFunction *SILGenModule::emitProtocolWitness(
909909
witness.getEnterIsolation());
910910

911911
emitLazyConformancesForFunction(f);
912+
913+
if (auto isolation = getSILFunctionTypeActorIsolation(
914+
reqtSubstTy, requirement, witnessRef)) {
915+
f->setActorIsolation(*isolation);
916+
}
917+
912918
return f;
913919
}
914920

0 commit comments

Comments
 (0)