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-15227] MainActor static variable initialization not enforced on main thread. #57549

Closed
bradleymackey opened this issue Sep 22, 2021 · 7 comments · Fixed by #40652
Closed
Assignees
Labels
actor isolation Feature → concurrency: Actor isolation 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 let & var Feature: constant and variable declarations SILGen Area → compiler: The SIL generation stage static declarations Feature → declarations: Static declarations swift 5.5 unexpected behavior Bug: Unexpected behavior or incorrect output

Comments

@bradleymackey
Copy link
Contributor

bradleymackey commented Sep 22, 2021

Previous ID SR-15227
Radar rdar://problem/83411416
Original Reporter @bradleymackey
Type Bug
Status Closed
Resolution Done
Environment

swift-driver version: 1.26.9 Apple Swift version 5.5 (swiftlang-1300.0.31.1 clang-1300.0.29.1)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, Concurrency
Assignee @kavon
Priority Medium

md5: 084c5699ba4bca8acdf7ced11d06439a

cloned to:

Issue Description:

@MainActor 
struct Bar {
  init() { 
    print("bar init is main", Thread.isMainThread) 
  } 
  func barCall() { 
    print("bar call is main", Thread.isMainThread) 
  } 
} 

@MainActor 
struct Foo { 
  @MainActor 
  static let global = Foo() 

  init() { 
    print("foo init is main", Thread.isMainThread) 
    let b = Bar() 
    b.barCall() 
  } 

  func fooCall() { 
    print("foo call is main", Thread.isMainThread) 
  } 

} 

Task.detached { 
  await Foo.global.fooCall() 
} 
// prints: 
// foo init is main false 
// bar init is main false 
// bar call is main false 
// foo call is main true

While fooCall() is enforced on the main thread, the initialization of the static variable is not, which breaks the contract of @MainActor.

@typesanitizer
Copy link

@swift-ci create

@kavon
Copy link
Contributor

kavon commented Jan 20, 2022

Resolved in #40652

@bradleymackey
Copy link
Contributor Author

This issue is still present in Swift 5.6, as per the example above. Curiously, if `global` is changed to a `static var`, the issue goes away and everything runs on the main thread as expected. `static let` causes the non-MainActor behaviour.

@bradleymackey
Copy link
Contributor Author

See last comment

@kavon
Copy link
Contributor

kavon commented Mar 17, 2022

Thanks for verifying that it is still broken for the `let` case. I believe the reason why it makes a difference is that we typically don't apply isolation to the access of an isolated `let` within the same module, but because it's static, all accesses must be considered isolated, because the first access will trigger the initialization.

@kavon
Copy link
Contributor

kavon commented Mar 17, 2022

I've cloned this issue over to specifically handle the static-let here: https://bugs.swift.org/browse/SR-16009

@kavon
Copy link
Contributor

kavon commented Mar 17, 2022

So we'll consider this SR to be about the case where it was a var, which was also broken but was fixed. Since the static-let case is going to require a fix in a different part of the compiler, I decided to clone.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added static declarations Feature → declarations: Static declarations actor isolation Feature → concurrency: Actor isolation unexpected behavior Bug: Unexpected behavior or incorrect output let & var Feature: constant and variable declarations SILGen Area → compiler: The SIL generation stage swift 5.5 labels Apr 22, 2023
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
actor isolation Feature → concurrency: Actor isolation 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 let & var Feature: constant and variable declarations SILGen Area → compiler: The SIL generation stage static declarations Feature → declarations: Static declarations swift 5.5 unexpected behavior Bug: Unexpected behavior or incorrect output
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants