Skip to content

Commit 2246dd1

Browse files
authored
Merge pull request swiftlang#70951 from slavapestov/sendable-type-and-more
Fix @retroactive for conditional conformances, and more
2 parents c06d3ce + 5249432 commit 2246dd1

22 files changed

+150
-139
lines changed

include/swift/AST/ActorIsolation.h

Lines changed: 0 additions & 3 deletions
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/TypeCheckRequests.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2829,6 +2829,25 @@ class TypeWitnessRequest
28292829
void cacheResult(TypeWitnessAndDecl value) const;
28302830
};
28312831

2832+
class ReferencedAssociatedTypesRequest
2833+
: public SimpleRequest<ReferencedAssociatedTypesRequest,
2834+
TinyPtrVector<AssociatedTypeDecl *>(ValueDecl *),
2835+
RequestFlags::Cached> {
2836+
public:
2837+
using SimpleRequest::SimpleRequest;
2838+
2839+
private:
2840+
friend SimpleRequest;
2841+
2842+
// Evaluation.
2843+
TinyPtrVector<AssociatedTypeDecl *>
2844+
evaluate(Evaluator &evaluator, ValueDecl *req) const;
2845+
2846+
public:
2847+
// Caching.
2848+
bool isCached() const { return true; }
2849+
};
2850+
28322851
class ValueWitnessRequest
28332852
: public SimpleRequest<ValueWitnessRequest,
28342853
Witness(NormalProtocolConformance *, ValueDecl *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ SWIFT_REQUEST(TypeChecker, AssociatedConformanceRequest,
426426
ProtocolConformanceRef(NormalProtocolConformance *,
427427
Type, ProtocolDecl *, unsigned),
428428
SeparatelyCached, NoLocationInfo)
429+
SWIFT_REQUEST(TypeChecker, ReferencedAssociatedTypesRequest,
430+
TinyPtrVector<AssociatedTypeDecl *>(ValueDecl *),
431+
Cached, NoLocationInfo)
429432
SWIFT_REQUEST(TypeChecker, ValueWitnessRequest,
430433
Witness(NormalProtocolConformance *, ValueDecl *),
431434
SeparatelyCached, NoLocationInfo)

include/swift/AST/Types.h

Lines changed: 3 additions & 5 deletions
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

Lines changed: 0 additions & 3 deletions
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

Lines changed: 21 additions & 5 deletions
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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,8 @@ Type CompletionLookup::getTypeOfMember(const ValueDecl *VD,
637637
// τ_1_0(U) => U }
638638
auto subs = keyPathInfo.baseType->getMemberSubstitutions(SD);
639639

640+
// FIXME: The below should use substitution map substitution.
641+
640642
// If the keyPath result type has type parameters, that might affect the
641643
// subscript result type.
642644
auto keyPathResultTy =
@@ -800,21 +802,20 @@ void CompletionLookup::analyzeActorIsolation(
800802
// If the reference is 'async', all types must be 'Sendable'.
801803
if (Ctx.LangOpts.StrictConcurrencyLevel >= StrictConcurrency::Complete &&
802804
implicitlyAsync && T) {
803-
auto *M = CurrDeclContext->getParentModule();
804805
if (isa<VarDecl>(VD)) {
805-
if (!isSendableType(M, T)) {
806+
if (!T->isSendableType()) {
806807
NotRecommended = ContextualNotRecommendedReason::CrossActorReference;
807808
}
808809
} else {
809810
assert(isa<FuncDecl>(VD) || isa<SubscriptDecl>(VD));
810811
// Check if the result and the param types are all 'Sendable'.
811812
auto *AFT = T->castTo<AnyFunctionType>();
812-
if (!isSendableType(M, AFT->getResult())) {
813+
if (!AFT->getResult()->isSendableType()) {
813814
NotRecommended = ContextualNotRecommendedReason::CrossActorReference;
814815
} else {
815816
for (auto &param : AFT->getParams()) {
816817
Type paramType = param.getPlainType();
817-
if (!isSendableType(M, paramType)) {
818+
if (!paramType->isSendableType()) {
818819
NotRecommended =
819820
ContextualNotRecommendedReason::CrossActorReference;
820821
break;

lib/IDE/IDETypeChecking.cpp

Lines changed: 3 additions & 1 deletion
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

Lines changed: 1 addition & 6 deletions
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

Lines changed: 5 additions & 6 deletions
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);

0 commit comments

Comments
 (0)