Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-12202] Property wrappers initialization is somehow artificially restricted for State #54627

Closed
DevAndArtist mannequin opened this issue Feb 13, 2020 · 9 comments
Closed
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself property wrappers Feature: property wrappers

Comments

@DevAndArtist
Copy link
Mannequin

DevAndArtist mannequin commented Feb 13, 2020

Previous ID SR-12202
Radar rdar://problem/52280477
Original Reporter @DevAndArtist
Type Bug
Status Resolved
Resolution Done
Environment

Apple Swift version 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15)

Additional Detail from JIRA
Votes 2
Component/s Compiler
Labels Bug, PropertyWrappers
Assignee @DevAndArtist
Priority Medium

md5: 8aaf5e4f262a6c145f3c7cad19fdf8c6

Issue Description:

This general property wrapper works as expected:

@propertyWrapper
struct W<T> { var wrappedValue: T }
struct S {
  @W var value: Int
  init(value: Int) {
    // this works because, what the compiler will substitute
    // the next line with `self._value = _W(wrappedValue: value)`
    self.value = value
  }
}

This one from SwiftUI doesn't for some reason:

import SwiftUI

struct V: View {
  @State var value: Int

  init(value: Int) {
    // error: 'self' used before all stored properties are initialized
    // error: Return from initializer without initializing all stored properties
    self.value = value
  }

  var body: Never {
    fatalError()
  }
}

Expected behavior is that the compiler substitute the above line like with every other property wrapper, which would be `self._value = State(wrappedValue: value)`.

@theblixguy
Copy link
Collaborator

Weird, looking at the generated SILGen'd output it seems like the backing property's initializer is not being called, before the setter is called.

@theblixguy
Copy link
Collaborator

Okay, after digging a bit, it seems like this isn't a bug. It's because the wrappedValue's setter is non-mutating (and State is a value type), and so we don't rewrite the assignment into an initialization.

It's also not tied to State, for example:

@propertyWrapper
struct Foo<T> {
  private var _value: T

  init(wrappedValue value: T) {
    _value = value
  }

  var wrappedValue: T {
    get { return _value }
    nonmutating set { fatalError("unimplemented") }
  }
}

struct Bar {
  @Foo var value: Int

  init(value: Int) {
    self.value = value
  }
}

although I suppose the diagnostics could be a bit better.

@DevAndArtist
Copy link
Mannequin Author

DevAndArtist mannequin commented Feb 13, 2020

Isn‘t this the other way around then? How is the setter even related to this as we still need to initialize the property wrapper first and therefore substitute the whole line. The initialization isn‘t really going through the computed property.

@DevAndArtist
Copy link
Mannequin Author

DevAndArtist mannequin commented Feb 13, 2020

I mean, this rule says nothing about the setter kind. https://forums.swift.org/t/why-does-this-property-wrapper-code-compile/31931/6

@DevAndArtist
Copy link
Mannequin Author

DevAndArtist mannequin commented Feb 13, 2020

Okay it also seems to happen if `wrappedValue` is get-only, but this rule isn‘t about that but rather about initialization similar to like out of line initialization but from within the init context.

@beccadax
Copy link
Contributor

@swift-ci create

@hborla
Copy link
Member

hborla commented Mar 17, 2020

This is due to an artificial limitation in the compiler's implementation of property wrappers. The workaround is to initialize the backing storage directly via _value in V.init:

  init(value: Int) {
    self._value = State(wrappedValue: value)
  }

@hborla
Copy link
Member

hborla commented Jan 12, 2021

This should be fixed by #35218

@hborla
Copy link
Member

hborla commented Jan 20, 2021

This is fixed. Could you please verify using the latest main development snapshot from https://swift.org/download/#snapshots ? Thank you!

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself property wrappers Feature: property wrappers
Projects
None yet
Development

No branches or pull requests

3 participants