swiftlang / swift

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

[SR-13142] Property wrapper that has a stored property with another PW raises compile time error in initialization #55589

Open swift-ci opened 4 years ago

swift-ci commented 4 years ago
Previous ID SR-13142
Radar rdar://problem/65115564
Original Reporter akaralar (JIRA User)
Type Bug
Environment Apple Swift version 5.3 (swiftlang-1200.0.16.9 clang-1200.0.22.5) Target: x86_64-apple-darwin19.5.0 macOS Catalina 10.15.5 (19F101) Xcode Version 12.0 beta (12A6159)
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 1 | |Component/s | | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 1c30f84090b7a2a317091e8ff055868b

Issue Description:

I'm trying to implement a property wrapper `LazyConstant` using `Lazy` property wrapper in the SE proposal.

Lazy

@propertyWrapper
public enum Lazy<Value> {
    case uninitialized(() -> Value)
    case initialized(Value)    

    public init(wrappedValue: @autoclosure @escaping () -> Value) {
        self = .uninitialized(wrappedValue)
    }    

    public var wrappedValue: Value {
        mutating get {
            switch self {
            case let .uninitialized(initializer):
                let value = initializer()
                self = .initialized(value)
                return value
            case let .initialized(value):
                return value
            }
        }
        set {
            self = .initialized(newValue)
        }
    }
}

LazyConstant

@propertyWrapper
public struct LazyConstant<Value> {
    @Lazy private var storage: Value    

    public init(wrappedValue: @autoclosure @escaping () -> Value) {
        storage = wrappedValue() // -> compile error here, 1- Return from initializer without initializing all stored properties, 2- 'self' used before all stored properties are initialized
    }

    public var wrappedValue: Value {
        mutating get {
            return storage
        }
    }
}

However if I change the line with the error to be

_storage = Lazy(wrappedValue: wrappedValue())

it compiles and functions correctly.

typesanitizer commented 4 years ago

@swift-ci create

tymurmustafaiev commented 1 year ago

Any updates on this? 🙏

AnthonyLatsis commented 1 year ago

Reduced:

@propertyWrapper
struct Wrapper {
  var wrappedValue: Bool

  init(wrappedValue: @autoclosure () -> Bool) {
    self.wrappedValue = true
  }
}

func test() {
  @Wrapper var storage: Bool
  storage = true
}

Tested with 23e2f345b51.