Skip to content

Commit 2fb76a4

Browse files
authored
Merge pull request #80333 from tshortli/clock-measure-unsafe-inherit-executor
2 parents cba4aeb + 2f78ba8 commit 2fb76a4

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,8 +2199,11 @@ void swift::introduceUnsafeInheritExecutorReplacements(
21992199
if (lookup.empty())
22002200
return;
22012201

2202-
auto baseNominal = base->getAnyNominal();
2203-
if (!baseNominal || !inConcurrencyModule(baseNominal))
2202+
SmallVector<NominalTypeDecl *, 4> nominalTypes;
2203+
namelookup::tryExtractDirectlyReferencedNominalTypes(base, nominalTypes);
2204+
if (llvm::none_of(nominalTypes, [](NominalTypeDecl *baseNominal) {
2205+
return inConcurrencyModule(baseNominal);
2206+
}))
22042207
return;
22052208

22062209
auto isReplaceable = [&](ValueDecl *decl) {

stdlib/public/Concurrency/Clock.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,22 @@ extension Clock {
7272
isolation: isolated (any Actor)? = #isolation,
7373
_ work: () async throws -> Void
7474
) async rethrows -> Instant.Duration {
75-
try await measure(work)
75+
let start = now
76+
try await work()
77+
let end = now
78+
return start.duration(to: end)
7679
}
7780

81+
// Note: hack to stage out @_unsafeInheritExecutor forms of various functions
82+
// in favor of #isolation. The _unsafeInheritExecutor_ prefix is meaningful
83+
// to the type checker.
84+
//
85+
// This function also doubles as an ABI-compatibility shim predating the
86+
// introduction of #isolation.
7887
@available(SwiftStdlib 5.7, *)
88+
@_silgen_name("$ss5ClockPsE7measurey8DurationQzyyYaKXEYaKF")
7989
@_unsafeInheritExecutor // for ABI compatibility
80-
@usableFromInline
81-
internal func measure(
90+
public func _unsafeInheritExecutor_measure(
8291
_ work: () async throws -> Void
8392
) async rethrows -> Instant.Duration {
8493
let start = now

test/Concurrency/unsafe_inherit_executor.swift

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,10 @@ enum MyError: Error {
9292
case fail
9393
}
9494

95+
protocol P {}
96+
9597
@_unsafeInheritExecutor
96-
func unsafeCallerAvoidsNewLoop(clock: some Clock) async throws {
98+
func unsafeCallerAvoidsNewLoop() async throws {
9799
// expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}
98100

99101
_ = await withUnsafeContinuation { (continuation: UnsafeContinuation<Int, Never>) in
@@ -129,13 +131,6 @@ func unsafeCallerAvoidsNewLoop(clock: some Clock) async throws {
129131
func operation() async throws -> Int { 7 }
130132
try await TL.$string.withValue("hello", operation: operation)
131133

132-
// FIXME: Clock.measure does not currently support this hack.
133-
// expected-error@+1{{#isolation (introduced by a default argument) cannot be used within an '@_unsafeInheritExecutor' function}}
134-
_ = try! await clock.measure {
135-
print("so very slow")
136-
try await Task.sleep(nanoseconds: 500)
137-
}
138-
139134
_ = await withDiscardingTaskGroup(returning: Int.self) { group in
140135
group.addTask {
141136
print("hello")
@@ -173,6 +168,32 @@ func unsafeCallerAvoidsNewLoop(clock: some Clock) async throws {
173168
}
174169
}
175170

171+
@_unsafeInheritExecutor
172+
func unsafeClockCaller(
173+
specificClock: ContinuousClock,
174+
genericClock: some Clock,
175+
existentialClock: any Clock,
176+
existentialCompositionClock: any P & Clock,
177+
) async throws {
178+
// expected-warning@-6{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}
179+
180+
_ = try! await specificClock.measure {
181+
try await Task.sleep(nanoseconds: 500)
182+
}
183+
184+
_ = try! await genericClock.measure {
185+
try await Task.sleep(nanoseconds: 500)
186+
}
187+
188+
_ = try! await existentialClock.measure {
189+
try await Task.sleep(nanoseconds: 500)
190+
}
191+
192+
_ = try! await existentialCompositionClock.measure {
193+
try await Task.sleep(nanoseconds: 500)
194+
}
195+
}
196+
176197
@_unsafeInheritExecutor
177198
func _unsafeInheritExecutor_hacky() async { }
178199
// expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}

0 commit comments

Comments
 (0)