Skip to content

Commit ba43a4d

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.
1 parent 3253a4f commit ba43a4d

File tree

1 file changed

+6
-132
lines changed

1 file changed

+6
-132
lines changed

lib/Sema/TypeCheckConcurrency.cpp

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

@@ -549,137 +548,11 @@ static bool isSendableClosure(
549548

550549
/// Determine whether the given type is suitable as a concurrent value type.
551550
bool swift::isSendableType(ModuleDecl *module, Type type) {
552-
class IsSendable : public TypeVisitor<IsSendable, bool> {
553-
ModuleDecl *module;
554-
ProtocolDecl *SendableProto;
555-
556-
public:
557-
IsSendable(ModuleDecl *module) : module(module) {
558-
SendableProto = module->getASTContext().getProtocol(
559-
KnownProtocolKind::Sendable);
560-
}
561-
562-
#define ALWAYS_CONCURRENT_VALUE(Id) \
563-
bool visit##Id##Type(Id##Type *) { return true; }
564-
565-
#define UNEXPECTED_TYPE(Id) ALWAYS_CONCURRENT_VALUE(Id)
566-
567-
ALWAYS_CONCURRENT_VALUE(Error)
568-
ALWAYS_CONCURRENT_VALUE(Builtin)
569-
ALWAYS_CONCURRENT_VALUE(AnyMetatype)
570-
ALWAYS_CONCURRENT_VALUE(Module)
571-
572-
UNEXPECTED_TYPE(GenericTypeParam)
573-
UNEXPECTED_TYPE(DependentMember)
574-
UNEXPECTED_TYPE(GenericFunction)
575-
576-
#define TYPE(Id, Parent)
577-
578-
// Look through type sugar.
579-
#define SUGARED_TYPE(Id, Parent) \
580-
bool visit##Id##Type(Id##Type *type) { \
581-
return visit(type->getSinglyDesugaredType()); \
582-
}
583-
584-
// Unchecked and artificial types won't show up in well-formed code,
585-
// but don't trip over them.
586-
#define UNCHECKED_TYPE(Id, Parent) UNEXPECTED_TYPE(Id)
587-
#define ARTIFICIAL_TYPE(Id, Parent) UNEXPECTED_TYPE(Id)
588-
589-
#include "swift/AST/TypeNodes.def"
590-
591-
#undef UNEXPECTED_TYPE
592-
#undef ALWAYS_CONCURRENT_VALUE
593-
594-
bool visitForConformanceCheck(TypeBase *type) {
595-
if (!SendableProto)
596-
return true;
597-
598-
return !TypeChecker::conformsToProtocol(
599-
Type(type), SendableProto, module).isInvalid();
600-
}
601-
602-
bool visitTupleType(TupleType *type) {
603-
for (Type elementType : type->getElementTypes()) {
604-
if (!visit(elementType))
605-
return false;
606-
}
607-
608-
return true;
609-
}
610-
611-
bool visitReferenceStorageType(ReferenceStorageType *type) {
612-
return visit(type->getReferentType());
613-
}
614-
615-
bool visitEnumType(EnumType *type) {
616-
return visitForConformanceCheck(type);
617-
}
618-
619-
bool visitStructType(StructType *type) {
620-
return visitForConformanceCheck(type);
621-
}
622-
623-
bool visitClassType(ClassType *type) {
624-
return visitForConformanceCheck(type);
625-
}
626-
627-
bool visitProtocolType(ProtocolType *type) {
628-
if (!SendableProto)
629-
return true;
630-
631-
return !TypeChecker::containsProtocol(
632-
Type(type), SendableProto, module).isInvalid();
633-
}
634-
635-
bool visitBoundGenericType(BoundGenericType *type) {
636-
return visitForConformanceCheck(type);
637-
}
638-
639-
bool visitDynamicSelfType(DynamicSelfType *type) {
640-
return visit(type->getSelfType());
641-
}
642-
643-
bool visitArchetypeType(ArchetypeType *type) {
644-
return visitForConformanceCheck(type);
645-
}
646-
647-
bool visitFunctionType(FunctionType *type) {
648-
// Concurrent function types meet the requirements.
649-
if (type->isSendable())
650-
return true;
651-
652-
// C and thin function types meeting the requirements because they
653-
// cannot have captures.
654-
switch (type->getExtInfo().getRepresentation()) {
655-
case FunctionTypeRepresentation::Block:
656-
case FunctionTypeRepresentation::Swift:
657-
return false;
658-
659-
case FunctionTypeRepresentation::CFunctionPointer:
660-
case FunctionTypeRepresentation::Thin:
661-
return true;
662-
}
663-
}
664-
665-
bool visitProtocolCompositionType(ProtocolCompositionType *type) {
666-
if (!SendableProto)
667-
return true;
668-
669-
return !TypeChecker::containsProtocol(type, SendableProto, module)
670-
.isInvalid();
671-
}
672-
673-
bool visitLValueType(LValueType *type) {
674-
return visit(type->getObjectType());
675-
}
676-
677-
bool visitInOutType(InOutType *type) {
678-
return visit(type->getObjectType());
679-
}
680-
} checker(module);
551+
auto proto = module->getASTContext().getProtocol(KnownProtocolKind::Sendable);
552+
if (!proto)
553+
return true;
681554

682-
return checker.visit(type);
555+
return !TypeChecker::conformsToProtocol(type, proto, module).isInvalid();
683556
}
684557

685558
static bool diagnoseNonConcurrentParameter(
@@ -3654,7 +3527,8 @@ static bool checkSendableInstanceStorage(
36543527
continue;
36553528
}
36563529

3657-
auto propertyType = dc->mapTypeIntoContext(property->getInterfaceType());
3530+
auto propertyType = dc->mapTypeIntoContext(property->getInterfaceType())
3531+
->getRValueType()->getReferenceStorageReferent();
36583532
if (!isSendableType(dc->getParentModule(), propertyType)) {
36593533
if (behavior == DiagnosticBehavior::Ignore)
36603534
return true;

0 commit comments

Comments
 (0)