Skip to content

Commit c13dd18

Browse files
committed
Sema: Diagnose the availability of global actor attributes. This includes SPI and resilience diagnostics.
1 parent 0e90e6a commit c13dd18

10 files changed

+113
-2
lines changed

lib/Sema/TypeCheckAccess.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -1677,6 +1677,15 @@ class DeclAvailabilityChecker : public DeclVisitor<DeclAvailabilityChecker> {
16771677
explicit DeclAvailabilityChecker(ExportContext where)
16781678
: Where(where) {}
16791679

1680+
void visit(Decl *D) {
1681+
DeclVisitor<DeclAvailabilityChecker>::visit(D);
1682+
1683+
if (auto globalActor = D->getGlobalActorAttr()) {
1684+
auto customAttr = globalActor->first;
1685+
checkType(customAttr->getType(), customAttr->getTypeRepr(), D);
1686+
}
1687+
}
1688+
16801689
// Force all kinds to be handled at a lower level.
16811690
void visitDecl(Decl *D) = delete;
16821691
void visitValueDecl(ValueDecl *D) = delete;

test/ClangImporter/objc_async.swift

+2
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ class BazFrame: NotIsolatedPictureFrame {
311311
}
312312
}
313313

314+
@available(SwiftStdlib 5.5, *)
314315
@SomeGlobalActor
315316
class BazFrameIso: PictureFrame { // expected-error {{global actor 'SomeGlobalActor'-isolated class 'BazFrameIso' has different actor isolation from main actor-isolated superclass 'PictureFrame'}}
316317
}
@@ -387,6 +388,7 @@ extension SomeWrapper: Sendable where T: Sendable {}
387388

388389

389390
// rdar://96830159
391+
@available(SwiftStdlib 5.5, *)
390392
@MainActor class SendableCompletionHandler {
391393
var isolatedThing: [String] = []
392394
// expected-note@-1 {{property declared here}}

test/Concurrency/concurrent_value_inference.swift

+3
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,11 @@ actor MyGlobalActor {
9191
static let shared = MyGlobalActor()
9292
}
9393

94+
@available(SwiftStdlib 5.1, *)
9495
@MyGlobalActor
9596
class C3 { }
9697

98+
@available(SwiftStdlib 5.1, *)
9799
class C4: C3 { }
98100

99101
// Make Sendable unavailable, but be sure not to diagnose it.
@@ -104,6 +106,7 @@ struct S2 {
104106
@available(*, unavailable)
105107
extension S2: Sendable { }
106108

109+
@available(SwiftStdlib 5.1, *)
107110
func testCV(
108111
c1: C1, c2: C2, c3: C3, c4: C4, s1: S1, e1: E1, e2: E2,
109112
gs1: GS1<Int>, gs2: GS2<Int>,

test/Concurrency/flow_isolation_nonstrict.swift

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ actor CheckDeinitFromActor {
3030
}
3131
}
3232

33+
@available(SwiftStdlib 5.1, *)
3334
@MainActor class X {
3435
var ns: NonSendableType = NonSendableType()
3536

test/Concurrency/require-explicit-sendable.swift

+6
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,16 @@ struct S11: Sendable {
101101
@_nonSendable public struct S12 { }
102102

103103
// Don't complain about global-actor-qualified classes or their subclasses.
104+
@available(SwiftStdlib 5.1, *)
104105
@MainActor
105106
open class TestThing {}
107+
108+
@available(SwiftStdlib 5.1, *)
106109
open class TestSubThing : TestThing {}
107110

111+
@available(SwiftStdlib 5.1, *)
108112
@MainActor(unsafe)
109113
open class TestThing2 {}
114+
115+
@available(SwiftStdlib 5.1, *)
110116
open class TestSubThing2 : TestThing2 {}

test/Concurrency/sendable_conformance_checking.swift

+3
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,10 @@ final class SubKlass: Klass<[S]> {}
159159
public struct S {}
160160

161161
// rdar://88700507 - redundant conformance of @MainActor-isolated subclass to 'Sendable'
162+
@available(SwiftStdlib 5.1, *)
162163
@MainActor class MainSuper {}
164+
165+
@available(SwiftStdlib 5.1, *)
163166
class MainSub: MainSuper, @unchecked Sendable {}
164167

165168
class SendableSuper: @unchecked Sendable {}

test/SILGen/functions_uninhabited_param.swift

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ enum E {
2525
static func f(_: E) {}
2626
}
2727

28+
@available(SwiftStdlib 5.1, *)
2829
@MainActor
2930
class Bar {
3031
var foo: (E) -> Void = { _ in }

test/SPI/spi_global_actor.swift

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// REQUIRES: concurrency
4+
5+
@available(SwiftStdlib 5.1, *)
6+
@_spi(Foo)
7+
@globalActor
8+
public struct SPIGA { // expected-note {{type declared here}}
9+
public actor Actor {}
10+
public static let shared = Actor()
11+
}
12+
13+
@available(SwiftStdlib 5.1, *)
14+
@SPIGA // expected-error {{cannot use struct 'SPIGA' here; it is SPI}}
15+
public struct PublicStruct {}
16+
17+
@available(SwiftStdlib 5.1, *)
18+
@_spi(Foo)
19+
@SPIGA
20+
public struct SPIStruct {}
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.50
2+
3+
// REQUIRES: concurrency
4+
// REQUIRES: OS=macosx
5+
6+
actor SomeActor {}
7+
8+
@globalActor struct AlwaysAvailableGA {
9+
static let shared = SomeActor()
10+
}
11+
12+
@available(macOS 10.51, *)
13+
@globalActor struct Available10_51GA {
14+
static let shared = SomeActor()
15+
}
16+
17+
@available(*, unavailable)
18+
@globalActor struct UnavailableGA { // expected-note {{'UnavailableGA' has been explicitly marked unavailable here}}
19+
static let shared = SomeActor()
20+
}
21+
22+
@AlwaysAvailableGA
23+
struct AlwaysAvailableWithAlwaysAvailableGA {}
24+
25+
@Available10_51GA // expected-error {{'Available10_51GA' is only available in macOS 10.51 or newer}}
26+
struct AlwaysAvailableWithAvailable10_51GA {} // expected-note {{add @available attribute to enclosing struct}}
27+
28+
@available(macOS 10.51, *)
29+
@Available10_51GA
30+
struct Always10_51WithAvailable10_51GA {}
31+
32+
@UnavailableGA // expected-error {{'UnavailableGA' is unavailable}}
33+
struct AlwaysAvailableWithUnavailableGA {}
34+
35+
@available(*, unavailable)
36+
@UnavailableGA
37+
struct UnavailableWithUnavailableGA {}

test/attr/attr_inlinable_global_actor.swift

+31-2
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,61 @@
22

33
// REQUIRES: concurrency
44

5+
@available(SwiftStdlib 5.1, *)
56
@globalActor
67
private struct PrivateGA { // expected-note 2 {{type declared here}}
78
actor Actor {}
89
static let shared = Actor()
910
}
1011

12+
@available(SwiftStdlib 5.1, *)
1113
@globalActor
1214
internal struct InternalGA { // expected-note {{type declared here}}
1315
actor Actor {}
1416
static let shared = Actor()
1517
}
1618

17-
@globalActor @usableFromInline
19+
@available(SwiftStdlib 5.1, *)
20+
@globalActor
21+
@usableFromInline
1822
internal struct UFIGA {
1923
@usableFromInline actor Actor {}
2024
@usableFromInline static let shared = Actor()
2125
}
2226

27+
@available(SwiftStdlib 5.1, *)
2328
@globalActor
2429
public struct PublicGA {
2530
public actor Actor {}
2631
public static let shared = Actor()
2732
}
2833

29-
// expected-error@+1 {{internal struct 'UFIStructPrivateGA' cannot have private global actor 'PrivateGA'}}
34+
// expected-error@+2 {{internal struct 'UFIStructPrivateGA' cannot have private global actor 'PrivateGA'}}
35+
@available(SwiftStdlib 5.1, *)
3036
@PrivateGA @usableFromInline internal struct UFIStructPrivateGA {} // expected-error {{global actor for struct 'UFIStructPrivateGA' must be '@usableFromInline' or public}}
37+
@available(SwiftStdlib 5.1, *)
3138
@InternalGA @usableFromInline internal struct UFIStructInternalGA {} // expected-error {{global actor for struct 'UFIStructInternalGA' must be '@usableFromInline' or public}}
39+
@available(SwiftStdlib 5.1, *)
3240
@UFIGA @usableFromInline internal struct UFIStructUFIGA {}
41+
@available(SwiftStdlib 5.1, *)
3342
@PublicGA @usableFromInline internal struct UFIStructPublicGA {}
43+
44+
@available(SwiftStdlib 5.1, *)
45+
@inlinable public func testNestedFuncs() {
46+
// FIXME: Functions isolated to non-resilient global actors nested in
47+
// inlinable functions should be diagnosed.
48+
@PrivateGA func inlineFuncPrivateGA() {}
49+
@InternalGA func inlineFuncInternalGA() {}
50+
@UFIGA func inlineFuncUFIGA() {}
51+
@PublicGA func inlineFuncPublicGA() {}
52+
}
53+
54+
@available(SwiftStdlib 5.1, *)
55+
@inlinable public func testNestedClosures() {
56+
// FIXME: Closures isolated to non-resilient global actors nested in
57+
// inlinable functions should be diagnosed.
58+
_ = { @PrivateGA in }
59+
_ = { @InternalGA in }
60+
_ = { @UFIGA in }
61+
_ = { @PublicGA in }
62+
}

0 commit comments

Comments
 (0)