Skip to content

Capturing a local var does not bind a task to the actor's context #63773

Open
@rnapier

Description

@rnapier

Description

Tasks that are bound to an actor's context are allowed to capture local vars. However, if no references are made to the actor's members, then local vars cannot be captured.

Steps to reproduce

The following code compiles, but breaks if the reference to actorVar is removed. ("Reference to captured var 'localVar' in concurrently-executing code")

actor A {
    var actorVar = 1
    func capture() {
        var localVar = 1
        Task {
            print(actorVar) // Removing this breaks the following line.
            print(localVar)
        }
    }
}

Conversely, MainActor is subtly different. The following compiles with no required access of a member:

@MainActor class A {
    func capture() {
        var localVar = 1
        Task {
            print(localVar)
        }
    }
}

Expected behavior

IMO, locally defined vars should be part of the actor's context, so they should be allowed to be captured and mutated identically to properties. Alternately, the system should be consistent and never allow local vars to be captured.

Environment
swift-driver version: 1.75.1 Apple Swift version 5.8 (swiftlang-5.8.0.117.11 clang-1403.0.22.8.60)
Target: arm64-apple-macosx13.0
Xcode 14.3
macOS 13.2.1 (22D68)

Metadata

Metadata

Assignees

No one assigned

    Labels

    actorFeature → concurrency: `actor` declarationsbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfconcurrencyFeature: umbrella label for concurrency language featuresswift 5.8type checkerArea → compiler: Semantic analysisunexpected errorBug: Unexpected error

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions