# Static var concurrency checking within Actor

**URL:** <https://forums.swift.org/t/static-var-concurrency-checking-within-actor/79573>\
**Category:** Using Swift\
**Tags:** concurrency, static, data-race, actors, swift6\
**Created:** [April 29, 2025, 1:54pm UTC](https://forums.swift.org/t/static-var-concurrency-checking-within-actor/79573 "2025-04-29T13:54:55Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tolga](https://avatars.discourse-cdn.com/v4/letter/t/c57346/32.png) [@Tolga](https://forums.swift.org/u/Tolga)\
**Post date:** [April 29, 2025, 1:54pm UTC](https://forums.swift.org/t/static-var-concurrency-checking-within-actor/79573/1 "2025-04-29T13:54:55Z")

</div>

Greetings!

So, I was trying to create a package, that receives some injected information at runtime and then offers all kinds of properties that get populated depending on that injected information.

While I was trying to make it work with Swift 6 (static vars are not allowed because of data-races), I ended up with something like this:

```swift
public actor TargetConfiguration
{
    enum Target
    {
        case target1
        case target2
        case target3
    }

    static var target: Target = .target1

    static func set(newTarget: Target)
    {
        target = newTarget
    }
    
    static var baseColorInternal: Color
    {
        switch target {
            case .target1:
                return .red
            case .target2:
                return .blue
            case .target3:
                return .green
        }
    }
    
    nonisolated
    static var baseColor: Color
    {
        baseColorInternal
    }
    
}

```

The usage would look like this:

```swift
@Test func example()
{
    #expect(TargetConfiguration.baseColor == .red)
    
    TargetConfiguration.set(newTarget: .target2)

    let color = TargetConfiguration.baseColor
    
    #expect(color == .blue)
}

```

Especially considering how much trouble we went through in some cases to get rid of these Swift 6 warnings / errors, I don't quite understand how this is allowed.

- I assume the private static var _target_ produces no warning, because it is isolated within the actor - alright.
- The private computed property _baseColorInternal_ is fine because it also is isolated within the actor - alright.
- But why can the non isolated static var _baseColor_ access the former _baseColorInternal_ without issue? It is accessing the isolated var from a non isolated context, isn't it?
- I also noticed I can **remove** non isolated from _baseColor_ and somehow the access in the tests still work just fine - no warning or anything!

It almost seems like non of these statics are isolated within the actor, but the compiler doesn't notice it.

Can I just assume it to be race-condition free and good to go for Swift6? It produces no warnings and no errors but it feels fishy.

If anyone knows anything, please let me know.

---

<div class="post-metadata">

**Author:** ![jamieQ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jamieq/32/5117_2.png) [@jamieQ](https://forums.swift.org/u/jamieQ)\
**Post date:** [April 29, 2025, 2:15pm UTC](https://forums.swift.org/t/static-var-concurrency-checking-within-actor/79573/2 "2025-04-29T14:15:39Z")

</div>

hi @Tolga, and welcome to the swift forums. you're correct to wonder about this behavior – this issue was raised somewhat recently in [this post](https://forums.swift.org/t/why-does-the-compiler-allow-static-properties-in-actors-without-await/76973), after which it was diagnosed as an implementation [bug](https://github.com/swiftlang/swift/issues/78435). i think this should be fixed in the upcoming 6.2 compiler release, where mutable statics within actors should be treated in the same manner as mutable global variables (namely, they require a global actor isolation annotation, or must in some other way be Sendable).

---

<div class="post-metadata">

**Author:** ![Tolga](https://avatars.discourse-cdn.com/v4/letter/t/c57346/32.png) [@Tolga](https://forums.swift.org/u/Tolga)\
**Post date:** [April 30, 2025, 6:51am UTC](https://forums.swift.org/t/static-var-concurrency-checking-within-actor/79573/3 "2025-04-30T06:51:24Z")

</div>

Thank you Jamie!

In that case I will add the isolation myself.

Maybe a small follow up question if this is allowed here (otherwise just close this thread):

Is there any way to make this actor (or struct) have a global static var that is used within the init and have both, the init _and_ the access to the properties nonisolated? I could not find a way without resorting to our own thread safe classes that are unchecked sendable.

---

<div class="post-metadata">

**Author:** ![jamieQ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jamieq/32/5117_2.png) [@jamieQ](https://forums.swift.org/u/jamieQ)\
**Post date:** [May 1, 2025, 12:04pm UTC](https://forums.swift.org/t/static-var-concurrency-checking-within-actor/79573/4 "2025-05-01T12:04:51Z")

</div>

> [@Tolga](#):
>
> Is there any way to make this actor (or struct) have a global static var that is used within the init and have both, the init _and_ the access to the properties nonisolated? I could not find a way without resorting to our own thread safe classes that are unchecked sendable.

my apologies, but i'm not sure i entirely follow what your end goal is. perhaps you could share a snippet of the sort of code you want to write when you have a chance.

---

<div class="post-metadata">

**Author:** ![Tolga](https://avatars.discourse-cdn.com/v4/letter/t/c57346/32.png) [@Tolga](https://forums.swift.org/u/Tolga)\
**Post date:** [May 5, 2025, 11:51am UTC](https://forums.swift.org/t/static-var-concurrency-checking-within-actor/79573/5 "2025-05-05T11:51:23Z")

</div>

No problem, I guess that was too abstract.

Basically I want to archive what was written in the test:

```swift
@Test func example()
{
    #expect(TargetConfiguration.baseColor == .red)
    
    TargetConfiguration.set(newTarget: .target2)

    let color = TargetConfiguration.baseColor
    
    #expect(color == .blue)
}

```

I want from this entity:

- Access static properties (without thread limitations)
- Set a static property (again, without thread limitations)
- Trigger no Swift 6 warnings :D

I also would not mind if this was an instance, but just using static getter / setter seemed nicer. More important is to archive something that is not limited to specific threads.

---

<div class="post-metadata">

**Author:** ![jamieQ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jamieq/32/5117_2.png) [@jamieQ](https://forums.swift.org/u/jamieQ)\
**Post date:** [May 5, 2025, 1:26pm UTC](https://forums.swift.org/t/static-var-concurrency-checking-within-actor/79573/6 "2025-05-05T13:26:39Z")

</div>

if the static values are to be read & written from arbitrary threads, and synchronous access is necessary, then they should probably be wrapped in a synchronization tool of some form\[1\]. depending on your deployment target you'll likely want to try using `Mutex`\[2\] which will ensure access to the shared mutable state is properly synchronized. e.g. something like:

```swift
public actor TargetConfiguration
{
    enum Target
    {
        case target1
        case target2
        case target3
    }

    static let target = Mutex<Target>(.target1)

    static func set(newTarget: Target)
    {
        target.withLock { $0 = newTarget }
    }
    
    // ...
}

```

i'm not sure if this suggestion is meaningfully different from what you've already tried however.

* * *

1. alternatively, explicitly marking them as `nonisolated(unsafe)` may be used as a means of opting-out of the isolation safety checks. as the keyword name implies, this comes with its own risks. 

2. or `OSAllocatedUnfairLock` on Darwin platforms that have earlier deployment targets

---

<div class="post-metadata">

**Author:** ![Tolga](https://avatars.discourse-cdn.com/v4/letter/t/c57346/32.png) [@Tolga](https://forums.swift.org/u/Tolga)\
**Post date:** [May 5, 2025, 2:13pm UTC](https://forums.swift.org/t/static-var-concurrency-checking-within-actor/79573/7 "2025-05-05T14:13:18Z")

</div>

Thank you very much, Jamie. 🙂

You basically confirmed what we agreed to go with internally, which serves as a nice morale boost that we were on the right track!  
But instead of Mutex we use some internal thread safe container, because we are not allowed to use iOS 18, yet.
