Skip to content

Commit a7f484b

Browse files
committed
AST: Clean up isSendableType()
1 parent 166d059 commit a7f484b

12 files changed

+42
-69
lines changed

include/swift/AST/ActorIsolation.h

-3
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ class AbstractClosureExpr;
3939
/// to avoid having to include Types.h.
4040
bool areTypesEqual(Type type1, Type type2);
4141

42-
/// Determine whether the given type is suitable as a concurrent value type.
43-
bool isSendableType(ModuleDecl *module, Type type);
44-
4542
/// Determines if the 'let' can be read from anywhere within the given module,
4643
/// regardless of the isolation or async-ness of the context in which
4744
/// the var is read.

include/swift/AST/Types.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -925,11 +925,9 @@ class alignas(1 << TypeAlignInBits) TypeBase
925925
/// Determines whether this type is an any actor type.
926926
bool isAnyActorType();
927927

928-
/// Returns true if this type is a Sendable type.
929-
bool isSendableType(DeclContext *declContext);
930-
931-
/// Returns true if this type is a Sendable type.
932-
bool isSendableType(ModuleDecl *parentModule);
928+
/// Returns true if this type conforms to Sendable, or if its a function type
929+
/// that is @Sendable.
930+
bool isSendableType();
933931

934932
/// Determines whether this type conforms or inherits (if it's a protocol
935933
/// type) from `DistributedActor`.

include/swift/SIL/SILType.h

-3
Original file line numberDiff line numberDiff line change
@@ -891,9 +891,6 @@ class SILType {
891891
/// Returns true if this function conforms to the Sendable protocol.
892892
bool isSendable(SILFunction *fn) const;
893893

894-
ProtocolConformanceRef conformsToProtocol(SILFunction *fn,
895-
ProtocolDecl *protocol) const;
896-
897894
/// False if SILValues of this type cannot be used outside the scope of their
898895
/// lifetime dependence.
899896
bool isEscapable() const;

lib/AST/Type.cpp

+21-5
Original file line numberDiff line numberDiff line change
@@ -580,12 +580,28 @@ bool TypeBase::isAnyActorType() {
580580
return false;
581581
}
582582

583-
bool TypeBase::isSendableType(DeclContext *ctx) {
584-
return isSendableType(ctx->getParentModule());
585-
}
583+
bool TypeBase::isSendableType() {
584+
auto proto = getASTContext().getProtocol(KnownProtocolKind::Sendable);
585+
if (!proto)
586+
return true;
587+
588+
// First check if we have a function type. If we do, check if it is
589+
// Sendable. We do this since functions cannot conform to protocols.
590+
if (auto *fas = getAs<SILFunctionType>())
591+
return fas->isSendable();
592+
if (auto *fas = getAs<AnyFunctionType>())
593+
return fas->isSendable();
586594

587-
bool TypeBase::isSendableType(ModuleDecl *parentModule) {
588-
return ::isSendableType(parentModule, Type(this));
595+
auto conformance = proto->getParentModule()->checkConformance(this, proto);
596+
if (conformance.isInvalid())
597+
return false;
598+
599+
// Look for missing Sendable conformances.
600+
return !conformance.forEachMissingConformance(
601+
[](BuiltinProtocolConformance *missing) {
602+
return missing->getProtocol()->isSpecificProtocol(
603+
KnownProtocolKind::Sendable);
604+
});
589605
}
590606

591607
bool TypeBase::isDistributedActor() {

lib/IDE/CompletionLookup.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -800,21 +800,20 @@ void CompletionLookup::analyzeActorIsolation(
800800
// If the reference is 'async', all types must be 'Sendable'.
801801
if (Ctx.LangOpts.StrictConcurrencyLevel >= StrictConcurrency::Complete &&
802802
implicitlyAsync && T) {
803-
auto *M = CurrDeclContext->getParentModule();
804803
if (isa<VarDecl>(VD)) {
805-
if (!isSendableType(M, T)) {
804+
if (!T->isSendableType()) {
806805
NotRecommended = ContextualNotRecommendedReason::CrossActorReference;
807806
}
808807
} else {
809808
assert(isa<FuncDecl>(VD) || isa<SubscriptDecl>(VD));
810809
// Check if the result and the param types are all 'Sendable'.
811810
auto *AFT = T->castTo<AnyFunctionType>();
812-
if (!isSendableType(M, AFT->getResult())) {
811+
if (!AFT->getResult()->isSendableType()) {
813812
NotRecommended = ContextualNotRecommendedReason::CrossActorReference;
814813
} else {
815814
for (auto &param : AFT->getParams()) {
816815
Type paramType = param.getPlainType();
817-
if (!isSendableType(M, paramType)) {
816+
if (!paramType->isSendableType()) {
818817
NotRecommended =
819818
ContextualNotRecommendedReason::CrossActorReference;
820819
break;

lib/IDE/IDETypeChecking.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ swift::getTopLevelDeclsForDisplay(ModuleDecl *M,
5252
!accessScope.isPublic() && !accessScope.isPackage())
5353
continue;
5454

55-
(void)swift::isSendableType(M, NTD->getDeclaredInterfaceType());
55+
auto proto = M->getASTContext().getProtocol(KnownProtocolKind::Sendable);
56+
if (proto)
57+
(void) M->lookupConformance(NTD->getDeclaredInterfaceType(), proto);
5658
}
5759
}
5860

lib/SIL/IR/SILType.cpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -1250,11 +1250,6 @@ SILType SILType::removingMoveOnlyWrapperToBoxedType(const SILFunction *fn) {
12501250
return SILType::getPrimitiveObjectType(newBoxType);
12511251
}
12521252

1253-
ProtocolConformanceRef
1254-
SILType::conformsToProtocol(SILFunction *fn, ProtocolDecl *protocol) const {
1255-
return fn->getParentModule()->checkConformance(getASTType(), protocol);
1256-
}
1257-
12581253
bool SILType::isSendable(SILFunction *fn) const {
1259-
return getASTType()->isSendableType(fn->getParentModule());
1254+
return getASTType()->isSendableType();
12601255
}

lib/SILOptimizer/Mandatory/FlowIsolation.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ static bool accessIsConcurrencySafe(ModuleDecl *module,
499499

500500
// must be accessible from nonisolated and Sendable
501501
return isLetAccessibleAnywhere(module, var)
502-
&& isSendableType(module, var->getTypeInContext());
502+
&& var->getTypeInContext()->isSendableType();
503503
}
504504

505505
/// \returns true iff the ref_element_addr instruction is only used
@@ -517,11 +517,10 @@ static bool onlyDeinitAccess(RefElementAddrInst *inst) {
517517
/// diagnostic if it is not Sendable. The diagnostic assumes that the access
518518
/// is happening in a deinit that uses flow-isolation.
519519
/// \returns true iff a diagnostic was emitted for this reference.
520-
static bool diagnoseNonSendableFromDeinit(ModuleDecl *module,
521-
RefElementAddrInst *inst) {
520+
static bool diagnoseNonSendableFromDeinit(RefElementAddrInst *inst) {
522521
VarDecl *var = inst->getField();
523522
Type ty = var->getTypeInContext();
524-
DeclContext* dc = inst->getFunction()->getDeclContext();
523+
DeclContext *dc = inst->getFunction()->getDeclContext();
525524

526525
// FIXME: we should emit diagnostics in other modes using:
527526
//
@@ -534,7 +533,7 @@ static bool diagnoseNonSendableFromDeinit(ModuleDecl *module,
534533
!= StrictConcurrency::Complete)
535534
return false;
536535

537-
if (isSendableType(module, ty))
536+
if (ty->isSendableType())
538537
return false;
539538

540539
auto &diag = var->getASTContext().Diags;
@@ -657,7 +656,7 @@ void AnalysisInfo::analyze(const SILArgument *selfParam) {
657656
continue;
658657

659658
// emit a diagnostic and skip if it's non-sendable in a deinit
660-
if (forDeinit && diagnoseNonSendableFromDeinit(module, refInst))
659+
if (forDeinit && diagnoseNonSendableFromDeinit(refInst))
661660
continue;
662661

663662
markPropertyUse(user);

lib/Sema/CodeSynthesis.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
361361
auto type = var->getTypeInContext();
362362
auto isolation = getActorIsolation(var);
363363
if (isolation.isGlobalActor()) {
364-
if (!isSendableType(decl->getModuleContext(), type) ||
364+
if (!type->isSendableType() ||
365365
var->getInitializerIsolation().isGlobalActor()) {
366366
// If different isolated stored properties require different
367367
// global actors, it is impossible to initialize this type.

lib/Sema/ConstraintSystem.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -2806,8 +2806,7 @@ ConstraintSystem::getTypeOfMemberReference(
28062806
FunctionType::ExtInfo info;
28072807

28082808
if (Context.LangOpts.hasFeature(Feature::InferSendableFromCaptures)) {
2809-
if (isPartialApplication(locator) &&
2810-
isSendableType(DC->getParentModule(), baseOpenedTy)) {
2809+
if (isPartialApplication(locator) && baseOpenedTy->isSendableType()) {
28112810
// Add @Sendable to functions without conditional conformances
28122811
functionType =
28132812
functionType

lib/Sema/TypeCheckAttr.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -6825,9 +6825,6 @@ void AttributeChecker::visitKnownToBeLocalAttr(KnownToBeLocalAttr *attr) {
68256825
}
68266826

68276827
void AttributeChecker::visitSendableAttr(SendableAttr *attr) {
6828-
6829-
auto dc = D->getDeclContext();
6830-
68316828
if ((isa<AbstractFunctionDecl>(D) || isa<AbstractStorageDecl>(D)) &&
68326829
!isAsyncDecl(cast<ValueDecl>(D))) {
68336830
auto value = cast<ValueDecl>(D);
@@ -6841,8 +6838,8 @@ void AttributeChecker::visitSendableAttr(SendableAttr *attr) {
68416838
}
68426839
// Prevent Sendable Attr from being added to methods of non-sendable types
68436840
if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(D)) {
6844-
if (auto selfdecl = funcDecl->getImplicitSelfDecl()) {
6845-
if (!isSendableType(dc->getParentModule(), selfdecl->getTypeInContext())) {
6841+
if (auto selfDecl = funcDecl->getImplicitSelfDecl()) {
6842+
if (!selfDecl->getTypeInContext()->isSendableType()) {
68466843
diagnose(attr->getLocation(), diag::nonsendable_instance_method)
68476844
.warnUntilSwiftVersion(6);
68486845
}

lib/Sema/TypeCheckConcurrency.cpp

+2-28
Original file line numberDiff line numberDiff line change
@@ -683,31 +683,6 @@ static bool isSendableClosure(
683683
return false;
684684
}
685685

686-
/// Determine whether the given type is suitable as a concurrent value type.
687-
bool swift::isSendableType(ModuleDecl *module, Type type) {
688-
auto proto = module->getASTContext().getProtocol(KnownProtocolKind::Sendable);
689-
if (!proto)
690-
return true;
691-
692-
// First check if we have a function type. If we do, check if it is
693-
// Sendable. We do this since functions cannot conform to protocols.
694-
if (auto *fas = type->getAs<SILFunctionType>())
695-
return fas->isSendable();
696-
if (auto *fas = type->getAs<AnyFunctionType>())
697-
return fas->isSendable();
698-
699-
auto conformance = module->checkConformance(type, proto);
700-
if (conformance.isInvalid())
701-
return false;
702-
703-
// Look for missing Sendable conformances.
704-
return !conformance.forEachMissingConformance(
705-
[](BuiltinProtocolConformance *missing) {
706-
return missing->getProtocol()->isSpecificProtocol(
707-
KnownProtocolKind::Sendable);
708-
});
709-
}
710-
711686
/// Add Fix-It text for the given nominal type to adopt Sendable.
712687
static void addSendableFixIt(
713688
const NominalTypeDecl *nominal, InFlightDiagnostic &diag, bool unchecked) {
@@ -4741,8 +4716,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
47414716
diagVar = originalVar;
47424717
}
47434718
if (var->isLet()) {
4744-
if (!isSendableType(var->getModuleContext(),
4745-
var->getInterfaceType())) {
4719+
if (!var->getInterfaceType()->isSendableType()) {
47464720
diagVar->diagnose(diag::shared_immutable_state_decl, diagVar)
47474721
.warnUntilSwiftVersion(6);
47484722
}
@@ -6356,7 +6330,7 @@ ActorReferenceResult ActorReferenceResult::forReference(
63566330
(!actorInstance || actorInstance->isSelf())) {
63576331
auto type =
63586332
fromDC->mapTypeIntoContext(declRef.getDecl()->getInterfaceType());
6359-
if (!isSendableType(fromDC->getParentModule(), type)) {
6333+
if (!type->isSendableType()) {
63606334
// Treat the decl isolation as 'preconcurrency' to downgrade violations
63616335
// to warnings, because violating Sendable here is accepted by the
63626336
// Swift 5.9 compiler.

0 commit comments

Comments
 (0)