@@ -502,7 +502,8 @@ void ClangImporter::Implementation::addSynthesizedTypealias(
502502
503503void ClangImporter::Implementation::addSynthesizedProtocolAttrs (
504504 NominalTypeDecl *nominal,
505- ArrayRef<KnownProtocolKind> synthesizedProtocolAttrs, bool isUnchecked) {
505+ ArrayRef<KnownProtocolKind> synthesizedProtocolAttrs, bool isUnchecked,
506+ bool isSuppressed) {
506507 auto &ctx = nominal->getASTContext ();
507508
508509 for (auto kind : synthesizedProtocolAttrs) {
@@ -511,7 +512,7 @@ void ClangImporter::Implementation::addSynthesizedProtocolAttrs(
511512 // ctx.getProtocol(kind) != nulltpr which would be nice.
512513 if (auto proto = ctx.getProtocol (kind))
513514 nominal->addAttribute (
514- new (ctx) SynthesizedProtocolAttr (proto, this , isUnchecked));
515+ new (ctx) SynthesizedProtocolAttr (proto, this , isUnchecked, isSuppressed ));
515516 }
516517}
517518
@@ -6602,7 +6603,7 @@ static bool conformsToProtocolInOriginalModule(NominalTypeDecl *nominal,
66026603 for (auto attr : nominal->getAttrs ().getAttributes <SynthesizedProtocolAttr>()) {
66036604 auto *otherProto = attr->getProtocol ();
66046605 if (otherProto == proto || otherProto->inheritsFrom (proto))
6605- return true ;
6606+ return !attr-> isSuppressed () ;
66066607 }
66076608
66086609 // Only consider extensions from the original module...or from an overlay
@@ -8910,6 +8911,7 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
89108911 std::optional<const clang::SwiftAttrAttr *> seenMainActorAttr;
89118912 const clang::SwiftAttrAttr *seenMutabilityAttr = nullptr ;
89128913 llvm::SmallSet<ProtocolDecl *, 4 > conformancesSeen;
8914+ const clang::SwiftAttrAttr *seenSendableSuppressionAttr = nullptr ;
89138915
89148916 auto importAttrsFromDecl = [&](const clang::NamedDecl *ClangDecl) {
89158917 //
@@ -9002,6 +9004,18 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
90029004 nominal->registerProtocolConformance (conformance, /* synthesized=*/ true );
90039005 }
90049006
9007+ if (swiftAttr->getAttribute () == " ~Sendable" ) {
9008+ auto *nominal = dyn_cast<NominalTypeDecl>(MappedDecl);
9009+ if (!nominal)
9010+ continue ;
9011+
9012+ seenSendableSuppressionAttr = swiftAttr;
9013+ addSynthesizedProtocolAttrs (nominal, {KnownProtocolKind::Sendable},
9014+ /* isUnchecked=*/ false ,
9015+ /* isSuppressed=*/ true );
9016+ continue ;
9017+ }
9018+
90059019 if (swiftAttr->getAttribute () == " sending" ) {
90069020 // Swallow this if the feature is not enabled.
90079021 if (!SwiftContext.LangOpts .hasFeature (Feature::SendingArgsAndResults))
@@ -9069,10 +9083,11 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
90699083 MappedDecl->getAttrs ().removeAttribute (attr);
90709084
90719085 // Some types have an implicit '@Sendable' attribute.
9072- if (ClangDecl->hasAttr <clang::SwiftNewTypeAttr>() ||
9073- ClangDecl->hasAttr <clang::EnumExtensibilityAttr>() ||
9074- ClangDecl->hasAttr <clang::FlagEnumAttr>() ||
9075- ClangDecl->hasAttr <clang::NSErrorDomainAttr>())
9086+ if ((ClangDecl->hasAttr <clang::SwiftNewTypeAttr>() ||
9087+ ClangDecl->hasAttr <clang::EnumExtensibilityAttr>() ||
9088+ ClangDecl->hasAttr <clang::FlagEnumAttr>() ||
9089+ ClangDecl->hasAttr <clang::NSErrorDomainAttr>()) &&
9090+ !seenSendableSuppressionAttr)
90769091 MappedDecl->addAttribute (new (SwiftContext)
90779092 SendableAttr (/* isImplicit=*/ true ));
90789093
@@ -9179,8 +9194,8 @@ void ClangImporter::Implementation::addExplicitProtocolConformance(
91799194 decl->getDeclaredInterfaceType (), conformsToValue);
91809195 }
91819196
9182- decl->addAttribute (new (SwiftContext)
9183- SynthesizedProtocolAttr ( protocol, this , false ));
9197+ decl->addAttribute (new (SwiftContext) SynthesizedProtocolAttr (
9198+ protocol, this , /* isUnchecked= */ false , /* isSuppressed= */ false ));
91849199 } else {
91859200 HeaderLoc attrLoc ((conformsToAttr)->getLocation ());
91869201 diagnose (attrLoc, diag::conforms_to_not_protocol, result,
0 commit comments