Skip to content
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

[SR-15745] Actor methods able to be called from escaping closure without await #58022

Closed
CharlesJS opened this issue Jan 17, 2022 · 1 comment
Labels
async & await Feature → concurrency: asynchronous function aka the async/await pattern bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself concurrency Feature: umbrella label for concurrency language features diagnostics QoI Bug: Diagnostics Quality of Implementation not a bug Resolution → not a bug: Reported as a bug but turned out to be expected behavior or programmer error

Comments

@CharlesJS
Copy link

Previous ID SR-15745
Radar rdar://90354322
Original Reporter @CharlesJS
Type Bug
Environment
$ swiftc --version
swift-driver version: 1.26.21 Apple Swift version 5.5.2 (swiftlang-1300.0.47.5 clang-1300.0.29.30)
Target: x86_64-apple-macosx12.0
Additional Detail from JIRA
Votes 3
Component/s swift
Labels Bug
Assignee None
Priority Medium

md5: 581829c2432961ebf61e130142bf32e5

Issue Description:

This compiles, and I'm pretty sure it shouldn't:

import Dispatch

func someFunctionThatDoesWhoKnowsWhatWithThis(closure: @escaping () -> ()) {
  DispatchQueue.main.async { closure() }
}

class SomeClass {}

actor Foo {
  var bar = SomeClass()

  func setBar(_ bar: SomeClass) { self.bar = bar }
 
  func baz() {
    someFunctionThatDoesWhoKnowsWhatWithThis {
      self.setBar(.init()) // shouldn't this require an `await`?
    }
  }
}

The code inside the `@escaping` closure is no longer running inside the actor's context, so it seems like it shouldn't be able to call the actor's methods without an `await`, and that this is therefore a bug.

Forum thread with related discussion: https://forums.swift.org/t/calling-escaping-closure-from-actor-context-why-dont-i-need-await-here/51029

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@DougGregor
Copy link
Member

As recently noted in the forum thread, this is an artifact of the compiler suppressing Sendable diagnostics in code that hasn't adopted concurrency. You can turn on completely checking manually with -Xfrontend -warn-concurrency (in Swift 5.6) or Swift 5.7's upcoming -strict-concurrency=complete. Doing so with my local Swift 5.7 build produces this:

t2.swift:4:30: warning: capture of 'closure' with non-sendable type '() -> ()' in a @Sendable closure
  DispatchQueue.main.async { closure() }
                             ^
t2.swift:4:30: note: a function type must be marked '@Sendable' to conform to 'Sendable'
  DispatchQueue.main.async { closure() }
                             ^

as it should.

@AnthonyLatsis AnthonyLatsis added concurrency Feature: umbrella label for concurrency language features compiler The Swift compiler in itself async & await Feature → concurrency: asynchronous function aka the async/await pattern not a bug Resolution → not a bug: Reported as a bug but turned out to be expected behavior or programmer error diagnostics QoI Bug: Diagnostics Quality of Implementation and removed swift labels Jan 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
async & await Feature → concurrency: asynchronous function aka the async/await pattern bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself concurrency Feature: umbrella label for concurrency language features diagnostics QoI Bug: Diagnostics Quality of Implementation not a bug Resolution → not a bug: Reported as a bug but turned out to be expected behavior or programmer error
Projects
None yet
Development

No branches or pull requests

3 participants