swiftlang / swift

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

PropertyWrapper compilation fails if BUILD_LIBRARY_FOR_DISTRIBUTION is enabled #67733

Open tymurmustafaiev opened 1 year ago

tymurmustafaiev commented 1 year ago

Description propertyWrapper requires to be initialised with underscore _ if BUILD_LIBRARY_FOR_DISTRIBUTION is enabled. I'm trying to build static library, and my code has some propertyWrappers. If I enable BUILD_LIBRARY_FOR_DISTRIBUTION, compilation fails with error: Variable x used before being initialized. However, If I change nesting, which you can find in Steps to Reproduce section, it will succeed. At the bottom, you can find a sample project 🙏

Steps to reproduce Try to add structure inside extension of a class and add a property wrapper as a variable inside. This code fails:

public final class EvolutionInteractor {
     ...
}

public extension EvolutionInteractor {
    struct Model {
        @Wrapper public var title: String = ""
        @Wrapper public var icon: UIImage?
        @Wrapper public var isEnabled: Bool
        let action: () -> Void

        public init(
            title: String,
            icon: UIImage? = nil,
            isEnabled: Bool = true,
            action: @escaping () -> Void
        ) {
            self.title = title
            self.icon = icon
            self.isEnabled = isEnabled
            self.action = action
        }
    }
}

But this one works fine:

public final class EvolutionInteractor {
     struct Model {
        @Wrapper public var title: String = ""
        @Wrapper public var icon: UIImage?
        @Wrapper public var isEnabled: Bool
        let action: () -> Void

        public init(
            title: String,
            icon: UIImage? = nil,
            isEnabled: Bool = true,
            action: @escaping () -> Void
        ) {
            self.title = title
            self.icon = icon
            self.isEnabled = isEnabled
            self.action = action
        }
    }
    public init() {}

    public func foo() {}
    public func bar() {}
}

You can try out sample project to see more details. It will work as well if I initialize it directly using underscore: self._title = .init(wrappedValue: title) and so on, but this is not an option as I have a lot of classes with similar code and it does work without nesting.

Expected behavior I expect this to be compiled in same nesting as I have in all my project. I can't change all code to second option because it's a lot of changes.

Screenshots Failed build: fail1 Successful builds: Moved struct inside class body: success1 Added one more layer of nesting inside extension:

success2

Environment

Here you can find sample project: https://github.com/tymurmustafaiev/evolution-test

tymurmustafaiev commented 1 year ago

👋 Does anybody know how this can be fixed locally without code changes?