Skip to content

Commit 68bb691

Browse files
authored
Merge pull request #42032 from DougGregor/nonsendable-availability
Add @available attributes on the implicit "extension" for @_nonSendable types
2 parents c03e8b5 + 5e50ee8 commit 68bb691

File tree

3 files changed

+68
-11
lines changed

3 files changed

+68
-11
lines changed

include/swift/AST/Attr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ class DeclAttribute : public AttributeBase {
291291
OnAnyClangDecl = 1ull << (unsigned(DeclKindIndex::Last_Decl) + 17),
292292
};
293293

294+
static_assert(
295+
(unsigned(DeclKindIndex::Last_Decl) + 17) < 64,
296+
"Overflow decl attr options bitfields");
297+
294298
LLVM_READNONE
295299
static uint64_t getOptions(DeclAttrKind DK);
296300

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4420,6 +4420,43 @@ bool swift::checkSendableConformance(
44204420
return checkSendableInstanceStorage(nominal, conformanceDC, check);
44214421
}
44224422

4423+
/// Add "unavailable" attributes to the given extension.
4424+
static void addUnavailableAttrs(ExtensionDecl *ext, NominalTypeDecl *nominal) {
4425+
ASTContext &ctx = nominal->getASTContext();
4426+
llvm::VersionTuple noVersion;
4427+
4428+
// Add platform-version-specific @available attributes.
4429+
for (auto available : nominal->getAttrs().getAttributes<AvailableAttr>()) {
4430+
if (available->Platform == PlatformKind::none)
4431+
continue;
4432+
4433+
auto attr = new (ctx) AvailableAttr(
4434+
SourceLoc(), SourceRange(),
4435+
available->Platform,
4436+
available->Message,
4437+
"", nullptr,
4438+
available->Introduced.getValueOr(noVersion), SourceRange(),
4439+
available->Deprecated.getValueOr(noVersion), SourceRange(),
4440+
available->Obsoleted.getValueOr(noVersion), SourceRange(),
4441+
PlatformAgnosticAvailabilityKind::Unavailable,
4442+
/*implicit=*/true,
4443+
available->IsSPI);
4444+
ext->getAttrs().add(attr);
4445+
}
4446+
4447+
// Add the blanket "unavailable".
4448+
4449+
auto attr = new (ctx) AvailableAttr(SourceLoc(), SourceRange(),
4450+
PlatformKind::none, "", "", nullptr,
4451+
noVersion, SourceRange(),
4452+
noVersion, SourceRange(),
4453+
noVersion, SourceRange(),
4454+
PlatformAgnosticAvailabilityKind::Unavailable,
4455+
false,
4456+
false);
4457+
ext->getAttrs().add(attr);
4458+
}
4459+
44234460
ProtocolConformance *GetImplicitSendableRequest::evaluate(
44244461
Evaluator &evaluator, NominalTypeDecl *nominal) const {
44254462
// Protocols never get implicit Sendable conformances.
@@ -4475,16 +4512,6 @@ ProtocolConformance *GetImplicitSendableRequest::evaluate(
44754512
-> NormalProtocolConformance * {
44764513
DeclContext *conformanceDC = nominal;
44774514
if (attrMakingUnavailable) {
4478-
llvm::VersionTuple NoVersion;
4479-
auto attr = new (ctx) AvailableAttr(SourceLoc(), SourceRange(),
4480-
PlatformKind::none, "", "", nullptr,
4481-
NoVersion, SourceRange(),
4482-
NoVersion, SourceRange(),
4483-
NoVersion, SourceRange(),
4484-
PlatformAgnosticAvailabilityKind::Unavailable,
4485-
false,
4486-
false);
4487-
44884515
// Conformance availability is currently tied to the declaring extension.
44894516
// FIXME: This is a hack--we should give conformances real availability.
44904517
auto inherits = ctx.AllocateCopy(makeArrayRef(
@@ -4497,7 +4524,7 @@ ProtocolConformance *GetImplicitSendableRequest::evaluate(
44974524
nominal->getModuleScopeContext(),
44984525
nullptr);
44994526
extension->setImplicit();
4500-
extension->getAttrs().add(attr);
4527+
addUnavailableAttrs(extension, nominal);
45014528

45024529
ctx.evaluator.cacheOutput(ExtendedTypeRequest{extension},
45034530
nominal->getDeclaredType());
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -typecheck -enable-library-evolution -target %target-cpu-apple-macosx12.0 -emit-module-interface-path %t/Library.swiftinterface -module-name Library %s
3+
4+
// REQUIRES: concurrency
5+
// REQUIRES: OS=macosx
6+
7+
@available(macOS 11.0, *)
8+
@_nonSendable
9+
public struct X { }
10+
11+
@_nonSendable
12+
public struct Y { }
13+
14+
// RUN: %FileCheck %s <%t/Library.swiftinterface
15+
// CHECK: @available(macOS 11.0, *)
16+
// CHECK-NEXT: public struct X
17+
18+
// CHECK: @available(macOS, unavailable, introduced: 11.0)
19+
// CHECK-NEXT: @available(*, unavailable)
20+
// CHECK-NEXT: extension Library.X{{( )?}}: @unchecked Swift.Sendable {
21+
22+
// CHECK: @available(*, unavailable)
23+
// CHECK-NEXT: extension Library.Y{{( )?}}: @unchecked Swift.Sendable {
24+
25+
// RUN: %target-swift-frontend -typecheck -enable-library-evolution -target %target-cpu-apple-macosx12.0 -emit-module-interface-path %t/Library.swiftinterface -DLIBRARY -module-name Library %s -module-interface-preserve-types-as-written
26+
// RUN: %FileCheck %s <%t/Library.swiftinterface

0 commit comments

Comments
 (0)