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-11209] Conditional projected property #53608

Open
DevAndArtist mannequin opened this issue Jul 25, 2019 · 4 comments
Open

[SR-11209] Conditional projected property #53608

DevAndArtist mannequin opened this issue Jul 25, 2019 · 4 comments
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 Jul 25, 2019

Previous ID SR-11209
Radar None
Original Reporter @DevAndArtist
Type Bug
Environment

Apple Swift version 5.1 (swiftlang-1100.0.257.2 clang-1100.0.31.3)
Target: x86_64-apple-darwin19.0.0

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, PropertyWrappers
Assignee None
Priority Medium

md5: 0a404a46a1f17b44ccbac70cb9f79037

Issue Description:

Related discussion: https://forums.swift.org/t/conditional-projected-property/27152

This code should compile and behave as expected:

@propertyWrapper
struct Wrapper<Value> {
  var wrappedValue: Value
}

extension Wrapper where Value == Int {
  var projectedValue: String {
    return "\(wrappedValue)"
  }
}

struct S {
  @Wrapper var a = "swift"
  @Wrapper var b = 42
  
  func foo() {
//    print(self.$a)
    print(self.$b)
  }
}

let s = S()
s.foo()

Because something like this does already work:

struct G<T> {}

extension G where T == Int {
  var p: Int {
    return 42
  }
}

extension G where T == String {
  var p: String {
    return "swift"
  }
}

let g_1 = G<Int>()
let g_2 = G<String>()

print(g_1.p, g_2.p)
@belkadan
Copy link
Contributor

cc @DougGregor

@DevAndArtist
Copy link
Mannequin Author

DevAndArtist mannequin commented Jul 29, 2019

Here is a concrete example where I need it. I want to extend `DelayedMutable` property wrapper which by itself does not project anything with a projecting behavior if the generic `Value` is some `Binding`. Please don't get confused with SwiftUI's Binding, this is a custom re-implementation for usage in UIKit on older OS's.

  // FIXME: Change to
  // ```
  // @DelayedMutable
  // public private(projection) var isEnabled: Binding<Bool>
  // ```
  private var _isEnabled = DelayedMutable<Binding<Bool>>()
  public var isEnabled: Binding<Bool> {
    get {
      return _isEnabled.wrappedValue
    }
    set {
      // FIXME: Move the following code to `willSet` when possible.
      do {
        setNeedsLayout()
        _updates[^\.isEnabled] = newValue.transaction.disablesAnimations
      }
      // Update the binding.
      _isEnabled.wrappedValue = newValue
    }
  }
  private var _$isEnabled: Bool {
    return _isEnabled.projectedValue
  }

@DevAndArtist
Copy link
Mannequin Author

DevAndArtist mannequin commented Nov 29, 2019

Ping @DougGregor. Is this a natural implication of the the property wrapper design?

@DougGregor
Copy link
Member

I think it's reasonable for this to work, yes.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
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

2 participants