Skip to content

Commit f51a050

Browse files
committed
[sil] Restrict sil_isolated to only being able to be applied to any actor types.
I also added some docs to SIL.rst about sil_isolated as well.
1 parent c1d0c8c commit f51a050

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

docs/SIL.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,18 @@ autorelease in the callee.
692692
type behaves like a non-generic type, as if the substitutions were
693693
actually applied to the underlying function type.
694694

695+
- SIL functions may optionally mark a function parameter as
696+
``@sil_isolated``. An ``@sil_isolated`` parameter must be one of:
697+
698+
- An actor or any actor type.
699+
- A generic type that conforms to Actor or AnyActor.
700+
701+
and must be the actor instance that a function is isolated to. Importantly
702+
this means that global actor isolated nominal types are never
703+
``@sil_isolated``. Only one parameter can ever be marked as ``@sil_isolated``
704+
since a function cannot be isolated to multiple actors at the same time.
705+
706+
695707
Async Functions
696708
```````````````
697709

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6580,6 +6580,35 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
65806580
"transferring result means all results are transferring");
65816581

65826582
// We should only ever have a single sil_isolated parameter.
6583+
bool foundIsolatedParameter = false;
6584+
for (const auto &parameterInfo : FTy->getParameters()) {
6585+
if (parameterInfo.hasOption(SILParameterInfo::Isolated)) {
6586+
auto argType = parameterInfo.getArgumentType(F.getModule(),
6587+
FTy,
6588+
F.getTypeExpansionContext());
6589+
if (argType->isOptional())
6590+
argType = argType->lookThroughAllOptionalTypes()->getCanonicalType();
6591+
6592+
auto genericSig = FTy->getInvocationGenericSignature();
6593+
auto &ctx = F.getASTContext();
6594+
auto *actorProtocol = ctx.getProtocol(KnownProtocolKind::Actor);
6595+
auto *anyActorProtocol = ctx.getProtocol(KnownProtocolKind::AnyActor);
6596+
bool genericTypeWithActorRequirement = llvm::any_of(
6597+
genericSig.getRequirements(), [&](const Requirement &other) {
6598+
if (other.getKind() != RequirementKind::Conformance)
6599+
return false;
6600+
if (other.getFirstType()->getCanonicalType() != argType)
6601+
return false;
6602+
auto *otherProtocol = other.getProtocolDecl();
6603+
return otherProtocol->inheritsFrom(actorProtocol) ||
6604+
otherProtocol->inheritsFrom(anyActorProtocol);
6605+
});
6606+
require(argType->isAnyActorType() || genericTypeWithActorRequirement,
6607+
"Only any actor types can be isolated");
6608+
require(!foundIsolatedParameter, "Two isolated parameters");
6609+
foundIsolatedParameter = true;
6610+
}
6611+
}
65836612
require(1 >= std::count_if(FTy->getParameters().begin(), FTy->getParameters().end(),
65846613
[](const SILParameterInfo &parameterInfo) {
65856614
return parameterInfo.hasOption(SILParameterInfo::Isolated);

0 commit comments

Comments
 (0)