Skip to content

Commit ff1cbea

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.
1 parent 20d7a6c commit ff1cbea

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
@@ -2386,6 +2386,49 @@ static void destructureYieldsForCoroutine(TypeConverter &TC,
23862386
}
23872387
}
23882388

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

lib/SILGen/SILGenType.cpp

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

905905
emitLazyConformancesForFunction(f);
906+
907+
if (auto isolation = getSILFunctionTypeActorIsolation(
908+
reqtSubstTy, requirement, witnessRef)) {
909+
f->setActorIsolation(*isolation);
910+
}
911+
906912
return f;
907913
}
908914

0 commit comments

Comments
 (0)