-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
False positive warning during the code analysis performed by SE-0430 "transferring" parameters and result values #73315
Comments
|
I have similar warnings in (real) code that involves continuation, as below: // Definition of asyncRead used below
func asyncRead(_ value: transferring @escaping (Result<Database, Error>) -> Void)
public func read<T>(
_ value: transferring @escaping (Database) throws -> transferring T
) async throws -> transferring T
{
try await withUnsafeThrowingContinuation { continuation in
asyncRead { result in
// `- warning: task-isolated value of type
// '(Result<Database, any Error>) -> Void' passed
// as a strongly transferred parameter.
do {
try continuation.resume(returning: value(result.get()))
} catch {
continuation.resume(throwing: error)
}
}
}
}I'm playing with My goal here is to help users use non-sendable values as freely as possible, both as captured inputs, and output of I don't really know if I'm facing compiler issues, or if I misunderstand the |
|
Hello, This issue is still there in Xcode 16 beta 1 (with I still assume that this warning is a false positive. Please somebody chime in if I'm wrong, so that I do not ship an incorrect workaround 🙏 My current workaround involves an unchecked sendable wrapper: func schedule(_ action: sending @escaping () -> Void) { }
// OK
func f1(_ closure: sending @escaping () -> Void) {
schedule {
closure()
}
}
// Compiler warning
func f2(_ closure: sending @escaping () -> Void) {
schedule {
schedule {
// `- warning: task-isolated value of type '() -> Void'
// passed as a strongly transferred parameter
closure()
}
}
}
// MARK: - Workaround
/// Helps compiler accept valid code it can't validate.
struct UncheckedSendableWrapper<Value>: @unchecked Sendable {
let value: Value
}
// No compiler warning
func f3(_ closure: sending @escaping () -> Void) {
schedule {
// TODO: remove wrapper when <https://github.com/apple/swift/issues/73315> is fixed.
let wrapper = UncheckedSendableWrapper(value: closure)
schedule {
wrapper.value()
}
}
} |
|
Here are two other snippets that reveal a variant of the warning. Maybe this is another compiler issue. The first snippet turns a call to // Similar to a future `DispatchQueue.async(execute:)`, according to
// <https://forums.swift.org/t/how-can-i-use-region-based-isolation/71426/5>
func async(execute work: sending @escaping () -> Void) { }
func awaitCompletion(_ closure: sending @escaping () -> Void) async {
await withUnsafeContinuation { continuation in
// ⚠️ Task-isolated value of type '() -> Void' passed as a strongly
// transferred parameter; later accesses could race; this is an
// error in the Swift 6 language mode.
async(execute: {
closure()
continuation.resume()
})
}
}A minimal sample code that reproduces this warning: // Minimal
func async(execute work: sending @escaping () -> Void) { }
func f(_ fn: () -> Void) { }
func noWarning(_ closure: sending @escaping () -> Void) async {
// No warning
async(execute: closure)
}
func warning1(_ closure: sending @escaping () -> Void) async {
f {
// ⚠️ Sending 'closure' risks causing data races; this is an error
// in the Swift 6 language mode
async(execute: closure)
}
}
func warning2(_ closure: sending @escaping () -> Void) async {
f {
// ⚠️ Task-isolated value of type '() -> Void' passed as a strongly
// transferred parameter; later accesses could race; this is an
// error in the Swift 6 language mode
async(execute: {
closure()
})
}
}Note that |
|
Case closed: those warnings are currently expected. See this forum post by @rjmccall. |
Description
The compiler emits false positive warnings whenever a value is transferred twice.
Reproduction
Expected behavior
The compiler emits no diagnostic
Environment
Additional information
I discovered this issue while exploring the possibilities evoked in this forum post.
I assumed that DispatchQueue.async WILL be modified so that it accepts a transferred closure instead of a Sendable closure.
I have some code that performs double async dispatch in order to avoid thread explosion (technique discussed in this forum post).
And that's how I had to transfer a closure twice, saw a warning, and opened this issue.
The text was updated successfully, but these errors were encountered: