swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.28k stars 10.33k forks source link

@propertyWrapper value in actor-isolated property 'home' can not be mutated from a non-isolated context #60926

Open m1entus opened 2 years ago

m1entus commented 2 years ago

Describe the bug Compiler shows warnings about can not be mutated from a non-isolated context in Xcode 14.0 when assigning value when using custom @propertyWrapper .

Steps To Reproduce

public struct Home {
}

@propertyWrapper
public final class MyPropertyWrapper<Value: Sendable>: @unchecked Sendable {
    public var wrappedValue: Value

    public init(wrappedValue: Value) {
        self.wrappedValue = wrappedValue
    }
}

public actor MyActor {

    @MyPropertyWrapper
    private var home: Home

    public init(home: Home) {
        self.home = home // Actor-isolated property 'home' can not be mutated from a non-isolated context; this is an error in Swift 6
    }
}

as a workaround it is possible to use MyPropertyWrapper<Home> and then warning dissapears.

public actor MyActor {

    private var home: MyPropertyWrapper<Home>

    public init(home: Home) {
        self.home = MyPropertyWrapper<Home>(wrappedValue: home)
    }
}

Expected behavior There should not be warning about Actor-isolated property 'home' can not be mutated from a non-isolated context when using @MyPropertyWrapper Warning not appear in Xcode 13.4.0.

Screenshots

Zrzut ekranu 2022-09-2 o 15 04 14

Environment (please fill out the following information)

Additional context Add any other context about the problem here.

theblixguy commented 2 years ago

Reduced:

public struct Home {}

public actor MyActor {

  private var home: Home {
    get { Home() }
    set { }
  }

  public init(home: Home) {
    self.home = home
  }
}
m1entus commented 2 years ago

Reduced:

public struct Home {}

public actor MyActor {

  private var home: Home {
    get { Home() }
    set { }
  }

  public init(home: Home) {
    self.home = home
  }
}

???

theblixguy commented 2 years ago

It’s a smaller version of the code that triggers the same warning. It’s nothing to do with property wrappers specifically, but with using a computed property.

m1entus commented 2 years ago

Aaa okay make sense now - thanks for explanation.

m1entus commented 2 years ago

Found out that this workaround works for me (instead of using computed property i use reference to propertyWrapper):

public actor MyActor {

    @MyPropertyWrapper
    private var home: Home

    public init(home: Home) {
        _home = MyPropertyWrapper<Home>(wrappedValue: home)
    }
}
MilezHigh commented 1 year ago

You need to make sure home is a published property

@Published var home: Home? = nil