Skip to content

Commit 68e909f

Browse files
committed
[Sema] Diagnose partial and unapplied func sendability
i.e. `S().f` is sendable if `S()` is a Sendable type Partial apply and unapplied methods of Sendable types should be marked as Sendable in the constraint system, including declarations and unapplied functions as parameters.
1 parent 5a66b62 commit 68e909f

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ FunctionType *ConstraintSystem::openFunctionType(
11601160
DeclContext *outerDC) {
11611161
if (auto *genericFn = funcType->getAs<GenericFunctionType>()) {
11621162
auto signature = genericFn->getGenericSignature();
1163-
1163+
//TO-DO Maybe update here
11641164
openGenericParameters(outerDC, signature, replacements, locator);
11651165

11661166
openGenericRequirements(outerDC, signature,
@@ -1672,6 +1672,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
16721672

16731673
OpenedTypeMap replacements;
16741674

1675+
// TO-DO check for sendable here and update type
16751676
AnyFunctionType *funcType = func->getInterfaceType()
16761677
->castTo<AnyFunctionType>();
16771678
auto openedType = openFunctionType(
@@ -1711,6 +1712,10 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
17111712
auto numLabelsToRemove = getNumRemovedArgumentLabels(
17121713
funcDecl, /*isCurriedInstanceReference=*/false, functionRefKind);
17131714

1715+
1716+
//check the base ... let's check
1717+
//funcType = funcType->withExtInfo(functy->getExtInfo().withConcurrent())->castTo<AnyFunctionType>();
1718+
17141719
auto openedType = openFunctionType(funcType, locator, replacements,
17151720
funcDecl->getDeclContext())
17161721
->removeArgumentLabels(numLabelsToRemove);
@@ -2624,6 +2629,14 @@ ConstraintSystem::getTypeOfMemberReference(
26242629
auto *functionType = fullFunctionType->getResult()->getAs<FunctionType>();
26252630
functionType = unwrapPropertyWrapperParameterTypes(*this, funcDecl, functionRefKind,
26262631
functionType, locator);
2632+
auto sendableProtocol = useDC->getParentModule()->getASTContext().getProtocol(KnownProtocolKind::Sendable);
2633+
// FIXME: Handle conditional conformances
2634+
auto baseSendable = TypeChecker::conformsToProtocol( baseOpenedTy, sendableProtocol, useDC->getParentModule());
2635+
2636+
if (!baseSendable.isInvalid()) {
2637+
functionType = functionType->withExtInfo(functionType->getExtInfo().withConcurrent())->getAs<FunctionType>();
2638+
}
2639+
26272640
// FIXME: Verify ExtInfo state is correct, not working by accident.
26282641
FunctionType::ExtInfo info;
26292642
openedType =

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,6 +2469,11 @@ namespace {
24692469
auto value = valueRef.getDecl();
24702470
auto loc = declRef->getLoc();
24712471

2472+
// for (auto arg : *declRef->getArgs()) {
2473+
//// if (swift::isSendableType(getDeclContext()->getParentModule(), arg))
2474+
// value->getAttrs().add(new (ctx) SendableAttr(true));
2475+
// }
2476+
24722477
//FIXME: Should this be subsumed in reference checking?
24732478
if (value->isLocalCapture())
24742479
checkLocalCapture(valueRef, loc, declRef);
@@ -2489,6 +2494,12 @@ namespace {
24892494
partialApply->base, memberRef->first, memberRef->second,
24902495
partialApply);
24912496

2497+
if (diagnosePartialApplySendability(partialApply->fn, partialApply->base, getDeclContext())){
2498+
if(auto funcdecl = dyn_cast<FuncDecl>(memberRef->first.getDecl())){
2499+
// Mark with @Sendable attribute implicitly if type is Sendable
2500+
funcdecl->getAttrs().add(new (ctx) SendableAttr(true));
2501+
}
2502+
}
24922503
partialApply->base->walk(*this);
24932504

24942505
return Action::SkipChildren(expr);
@@ -3105,6 +3116,11 @@ namespace {
31053116
getContextIsolation().isActorIsolated())
31063117
unsatisfiedIsolation = ActorIsolation::forNonisolated();
31073118

3119+
// move check for sendability of arguments earlier
3120+
if (!ctx.LangOpts.hasFeature(Feature::DeferredSendableChecking)) {
3121+
diagnoseApplyArgSendability(apply, getDeclContext());
3122+
}
3123+
31083124
// If there was no unsatisfied actor isolation, we're done.
31093125
if (!unsatisfiedIsolation)
31103126
return false;

lib/Sema/TypeCheckConcurrency.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,11 @@ bool isPotentiallyIsolatedActor(
548548
VarDecl *var, llvm::function_ref<bool(ParamDecl *)> isIsolated =
549549
[](ParamDecl *P) { return P->isIsolated(); });
550550

551+
/// Check whether the given PartialApplyThunk makes an unsatisfied isolation jump
552+
/// and if so, emit diagnostics for any nonsendable arguments to the apply.
553+
/// Add the Sendable attribute if this is a patial apply of a Sendable Type.
554+
bool diagnosePartialApplySendability(Expr *decl, Expr *base, const DeclContext *declContext);
555+
551556
/// Check whether the given ApplyExpr makes an unsatisfied isolation jump
552557
/// and if so, emit diagnostics for any nonsendable arguments to the apply
553558
bool diagnoseApplyArgSendability(

0 commit comments

Comments
 (0)