|
25 | 25 | #include "swift/AST/NameLookupRequests.h"
|
26 | 26 | #include "swift/AST/TypeCheckRequests.h"
|
27 | 27 | #include "swift/AST/TypeVisitor.h"
|
| 28 | +#include "swift/AST/ExistentialLayout.h" |
28 | 29 | #include "swift/Sema/IDETypeChecking.h"
|
29 | 30 |
|
30 | 31 | using namespace swift;
|
@@ -698,140 +699,12 @@ static bool isSendableClosure(
|
698 | 699 | return false;
|
699 | 700 | }
|
700 | 701 |
|
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; |
833 | 706 |
|
834 |
| - return checker.visit(type); |
| 707 | + return !TypeChecker::conformsToProtocol(type, proto, module).isInvalid(); |
835 | 708 | }
|
836 | 709 |
|
837 | 710 | static bool diagnoseNonConcurrentParameter(
|
@@ -3537,8 +3410,9 @@ static bool checkSendableInstanceStorage(
|
3537 | 3410 | continue;
|
3538 | 3411 | }
|
3539 | 3412 |
|
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)) { |
3542 | 3416 | if (behavior == DiagnosticBehavior::Ignore)
|
3543 | 3417 | return true;
|
3544 | 3418 | property->diagnose(diag::non_concurrent_type_member,
|
|
0 commit comments