Skip to content

Commit 3d49300

Browse files
authored
Merge pull request #70743 from hborla/inferred-preconcurrency
[Concurrency] Downgrade isolated call diagnostics when the callee has an inferred `@preconcurrency` annotation.
2 parents 043a13a + 813f952 commit 3d49300

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3341,7 +3341,7 @@ namespace {
33413341
} else {
33423342
if (calleeDecl) {
33433343
auto preconcurrency = getContextIsolation().preconcurrency() ||
3344-
calleeDecl->preconcurrency();
3344+
getActorIsolation(calleeDecl).preconcurrency();
33453345
ctx.Diags.diagnose(
33463346
apply->getLoc(), diag::actor_isolated_call_decl,
33473347
*unsatisfiedIsolation,
@@ -5135,7 +5135,8 @@ bool swift::contextRequiresStrictConcurrencyChecking(
51355135
// features.
51365136
if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
51375137
auto *nominal = extension->getExtendedNominal();
5138-
if (nominal && hasExplicitIsolationAttribute(nominal))
5138+
if (nominal && hasExplicitIsolationAttribute(nominal) &&
5139+
!getActorIsolation(nominal).preconcurrency())
51395140
return true;
51405141
}
51415142

test/Concurrency/predates_concurrency.swift

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ func testCalls(x: X) {
103103
let _: () -> Void = onMainActorAlways // expected-complete-tns-warning {{converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor 'MainActor'}}
104104

105105
// both okay with minimal/targeted... an error with complete.
106-
let c = MyModelClass() // expected-complete-tns-error {{call to main actor-isolated initializer 'init()' in a synchronous nonisolated context}}
107-
c.f() // expected-complete-tns-error {{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
106+
let c = MyModelClass() // expected-complete-tns-warning {{call to main actor-isolated initializer 'init()' in a synchronous nonisolated context}}
107+
c.f() // expected-complete-tns-warning {{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
108108
}
109109

110110
func testCallsWithAsync() async {
@@ -207,3 +207,41 @@ class C { // expected-complete-tns-note {{'C' does not conform to the 'Sendable'
207207
}
208208
}
209209

210+
@preconcurrency @MainActor
211+
class MainActorPreconcurrency {}
212+
213+
class InferMainActorPreconcurrency: MainActorPreconcurrency {
214+
static func predatesConcurrency() {}
215+
// expected-note@-1 {{calls to static method 'predatesConcurrency()' from outside of its actor context are implicitly asynchronous}}
216+
}
217+
218+
nonisolated func blah() {
219+
InferMainActorPreconcurrency.predatesConcurrency()
220+
// expected-warning@-1 {{call to main actor-isolated static method 'predatesConcurrency()' in a synchronous nonisolated context}}
221+
}
222+
223+
protocol NotIsolated {
224+
func requirement()
225+
// expected-complete-tns-note@-1 {{mark the protocol requirement 'requirement()' 'async' to allow actor-isolated conformances}}
226+
}
227+
228+
extension MainActorPreconcurrency: NotIsolated {
229+
func requirement() {}
230+
// expected-complete-tns-warning@-1 {{main actor-isolated instance method 'requirement()' cannot be used to satisfy nonisolated protocol requirement}}
231+
// expected-complete-tns-note@-2 {{add 'nonisolated' to 'requirement()' to make this instance method not isolated to the actor}}
232+
// expected-complete-tns-note@-3 {{calls to instance method 'requirement()' from outside of its actor context are implicitly asynchronous}}
233+
234+
235+
class Nested {
236+
weak var c: MainActorPreconcurrency?
237+
238+
func test() {
239+
// expected-complete-tns-note@-1 {{add '@MainActor' to make instance method 'test()' part of global actor 'MainActor'}}
240+
241+
if let c {
242+
c.requirement()
243+
// expected-complete-tns-warning@-1 {{call to main actor-isolated instance method 'requirement()' in a synchronous nonisolated context}}
244+
}
245+
}
246+
}
247+
}

0 commit comments

Comments
 (0)