Skip to content

Commit 14e601e

Browse files
committed
Replace the ad-hoc Sendable checking visitor with "conforms to protocol".
Now that we synthesize conformances for structural types to `Sendable`, we can just do this check. (cherry picked from commit ba43a4d)
1 parent fc612c8 commit 14e601e

File tree

1 file changed

+9
-135
lines changed

1 file changed

+9
-135
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 9 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/AST/NameLookupRequests.h"
2626
#include "swift/AST/TypeCheckRequests.h"
2727
#include "swift/AST/TypeVisitor.h"
28+
#include "swift/AST/ExistentialLayout.h"
2829
#include "swift/Sema/IDETypeChecking.h"
2930

3031
using namespace swift;
@@ -698,140 +699,12 @@ static bool isSendableClosure(
698699
return false;
699700
}
700701

701-
/// Determine whether the given type is suitable as a concurrent value type.
702-
bool swift::isSendableType(const DeclContext *dc, Type type) {
703-
class IsSendable : public TypeVisitor<IsSendable, bool> {
704-
DeclContext *dc;
705-
ProtocolDecl *SendableProto;
706-
707-
public:
708-
IsSendable(const DeclContext *dc)
709-
: dc(const_cast<DeclContext *>(dc)) {
710-
SendableProto = dc->getASTContext().getProtocol(
711-
KnownProtocolKind::Sendable);
712-
}
713-
714-
#define ALWAYS_CONCURRENT_VALUE(Id) \
715-
bool visit##Id##Type(Id##Type *) { return true; }
716-
717-
#define UNEXPECTED_TYPE(Id) ALWAYS_CONCURRENT_VALUE(Id)
718-
719-
ALWAYS_CONCURRENT_VALUE(Error)
720-
ALWAYS_CONCURRENT_VALUE(Builtin)
721-
ALWAYS_CONCURRENT_VALUE(AnyMetatype)
722-
ALWAYS_CONCURRENT_VALUE(Module)
723-
724-
UNEXPECTED_TYPE(GenericTypeParam)
725-
UNEXPECTED_TYPE(DependentMember)
726-
UNEXPECTED_TYPE(GenericFunction)
727-
728-
#define TYPE(Id, Parent)
729-
730-
// Look through type sugar.
731-
#define SUGARED_TYPE(Id, Parent) \
732-
bool visit##Id##Type(Id##Type *type) { \
733-
return visit(type->getSinglyDesugaredType()); \
734-
}
735-
736-
// Unchecked and artificial types won't show up in well-formed code,
737-
// but don't trip over them.
738-
#define UNCHECKED_TYPE(Id, Parent) UNEXPECTED_TYPE(Id)
739-
#define ARTIFICIAL_TYPE(Id, Parent) UNEXPECTED_TYPE(Id)
740-
741-
#include "swift/AST/TypeNodes.def"
742-
743-
#undef UNEXPECTED_TYPE
744-
#undef ALWAYS_CONCURRENT_VALUE
745-
746-
bool visitForConformanceCheck(TypeBase *type) {
747-
if (!SendableProto)
748-
return true;
749-
750-
return !TypeChecker::conformsToProtocol(
751-
Type(type), SendableProto, dc).isInvalid();
752-
}
753-
754-
bool visitTupleType(TupleType *type) {
755-
for (Type elementType : type->getElementTypes()) {
756-
if (!visit(elementType))
757-
return false;
758-
}
759-
760-
return true;
761-
}
762-
763-
bool visitReferenceStorageType(ReferenceStorageType *type) {
764-
return visit(type->getReferentType());
765-
}
766-
767-
bool visitEnumType(EnumType *type) {
768-
return visitForConformanceCheck(type);
769-
}
770-
771-
bool visitStructType(StructType *type) {
772-
return visitForConformanceCheck(type);
773-
}
774-
775-
bool visitClassType(ClassType *type) {
776-
return visitForConformanceCheck(type);
777-
}
778-
779-
bool visitProtocolType(ProtocolType *type) {
780-
if (!SendableProto)
781-
return true;
782-
783-
return !TypeChecker::containsProtocol(
784-
Type(type), SendableProto, dc).isInvalid();
785-
}
786-
787-
bool visitBoundGenericType(BoundGenericType *type) {
788-
return visitForConformanceCheck(type);
789-
}
790-
791-
bool visitDynamicSelfType(DynamicSelfType *type) {
792-
return visit(type->getSelfType());
793-
}
794-
795-
bool visitArchetypeType(ArchetypeType *type) {
796-
return visitForConformanceCheck(type);
797-
}
798-
799-
bool visitFunctionType(FunctionType *type) {
800-
// Concurrent function types meet the requirements.
801-
if (type->isSendable())
802-
return true;
803-
804-
// C and thin function types meeting the requirements because they
805-
// cannot have captures.
806-
switch (type->getExtInfo().getRepresentation()) {
807-
case FunctionTypeRepresentation::Block:
808-
case FunctionTypeRepresentation::Swift:
809-
return false;
810-
811-
case FunctionTypeRepresentation::CFunctionPointer:
812-
case FunctionTypeRepresentation::Thin:
813-
return true;
814-
}
815-
}
816-
817-
bool visitProtocolCompositionType(ProtocolCompositionType *type) {
818-
if (!SendableProto)
819-
return true;
820-
821-
return !TypeChecker::containsProtocol(type, SendableProto, dc)
822-
.isInvalid();
823-
}
824-
825-
bool visitLValueType(LValueType *type) {
826-
return visit(type->getObjectType());
827-
}
828-
829-
bool visitInOutType(InOutType *type) {
830-
return visit(type->getObjectType());
831-
}
832-
} checker(dc);
702+
bool swift::isSendableType(ModuleDecl *module, Type type) {
703+
auto proto = module->getASTContext().getProtocol(KnownProtocolKind::Sendable);
704+
if (!proto)
705+
return true;
833706

834-
return checker.visit(type);
707+
return !TypeChecker::conformsToProtocol(type, proto, module).isInvalid();
835708
}
836709

837710
static bool diagnoseNonConcurrentParameter(
@@ -3537,8 +3410,9 @@ static bool checkSendableInstanceStorage(
35373410
continue;
35383411
}
35393412

3540-
auto propertyType = dc->mapTypeIntoContext(property->getInterfaceType());
3541-
if (!isSendableType(dc, propertyType)) {
3413+
auto propertyType = dc->mapTypeIntoContext(property->getInterfaceType())
3414+
->getRValueType()->getReferenceStorageReferent();
3415+
if (!isSendableType(dc->getParentModule(), propertyType)) {
35423416
if (behavior == DiagnosticBehavior::Ignore)
35433417
return true;
35443418
property->diagnose(diag::non_concurrent_type_member,

0 commit comments

Comments
 (0)