swiftlang / swift

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

[SR-11638] willSet Property Observer Causes Infinite Recursion When Used With @Published #54049

Open swift-ci opened 5 years ago

swift-ci commented 5 years ago
Previous ID SR-11638
Radar None
Original Reporter dbianchi (JIRA User)
Type Bug
Environment Xcode 11.1 SwiftUI
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, PropertyWrappers | |Assignee | None | |Priority | Medium | md5: 0c530cc423fc2d327dd8653d13b23958

Issue Description:

If a property is using the `@Published` wrapper and the `willSet` property observer to set the value, invite recursion will occur as a result of the `willSet` observer being called indefinitely. If I remove the `@Published` wrapper, the bug does not exist.

@Published var someVariable: String = "" {
    willSet {
        someVariable = oldValue
    }
}
theblixguy commented 5 years ago

Reproducer that doesn't involve Combine:

@propertyWrapper
struct Foo {
  var wrappedValue: Int
}

struct Bar {
  @Foo var prop: Int = 0 { 
    willSet { prop = newValue }
  }
}

var bar = Bar()
bar.prop = 1 // Crash

If you replace willSet with didSet then you have the same issue as well.

theblixguy commented 5 years ago

As a workaround, you can do _someVariable.wrappedValue = <value> in the willSet/didSet and this will not cause an infinite recursion.