|
25 | 25 | #include "swift/AST/ProtocolConformance.h"
|
26 | 26 | #include "swift/AST/NameLookupRequests.h"
|
27 | 27 | #include "swift/AST/TypeCheckRequests.h"
|
28 |
| -#include "swift/AST/TypeVisitor.h" |
29 | 28 | #include "swift/AST/ExistentialLayout.h"
|
30 | 29 | #include "swift/Sema/IDETypeChecking.h"
|
31 | 30 |
|
@@ -549,137 +548,11 @@ static bool isSendableClosure(
|
549 | 548 |
|
550 | 549 | /// Determine whether the given type is suitable as a concurrent value type.
|
551 | 550 | 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; |
681 | 554 |
|
682 |
| - return checker.visit(type); |
| 555 | + return !TypeChecker::conformsToProtocol(type, proto, module).isInvalid(); |
683 | 556 | }
|
684 | 557 |
|
685 | 558 | static bool diagnoseNonConcurrentParameter(
|
@@ -3654,7 +3527,8 @@ static bool checkSendableInstanceStorage(
|
3654 | 3527 | continue;
|
3655 | 3528 | }
|
3656 | 3529 |
|
3657 |
| - auto propertyType = dc->mapTypeIntoContext(property->getInterfaceType()); |
| 3530 | + auto propertyType = dc->mapTypeIntoContext(property->getInterfaceType()) |
| 3531 | + ->getRValueType()->getReferenceStorageReferent(); |
3658 | 3532 | if (!isSendableType(dc->getParentModule(), propertyType)) {
|
3659 | 3533 | if (behavior == DiagnosticBehavior::Ignore)
|
3660 | 3534 | return true;
|
|
0 commit comments