|
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