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-13995] Some way to refer to outer generic parameters shadowed by an inner parameter with the same name #56390

Open
swift-ci opened this issue Dec 26, 2020 · 3 comments

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-13995
Radar rdar://problem/72864718
Original Reporter Jessy (JIRA User)
Type New Feature
Environment

Xcode 12.3 beta

Additional Detail from JIRA
Votes 0
Component/s
Labels New Feature
Assignee None
Priority Medium

md5: 2783c3ac914f337886bcd7289fdefffa

Issue Description:

Example: this results in the error "`Value` is not a member of `Binding<Value>`".

It makes for ugly naming.

import SwiftUI

public extension Binding {
  subscript<Key, Value>(
    key: Key,
    default default: Value
  ) -> Binding<Value>
  where Self.Value == [Key: Value] {
    .init(
      get: { wrappedValue[key, default: `default`] },
      set: { wrappedValue[key] = $0 }
    )
  }
}
@typesanitizer
Copy link

@swift-ci create

@slavapestov
Copy link
Member

"Self" is shorthand for "Binding<Value>" in this case. Even without "Self", there's no way to do what you want here, which is to refer to the "Value" generic parameter from the outer scope. Once a generic parameter name has been shadowed, any reference to that name will always refer to the innermost definition.

Perhaps the best way is to rename the "Value" generic parameter of the subscript to something else?

@swift-ci
Copy link
Collaborator Author

Comment by Jessy Catterwaul (JIRA)

_ Once a generic parameter name has been shadowed, any reference to that name will always refer to the innermost definition._

That doesn't seem correct to me, but I have to be missing something. Why has the following compiled fine over the past year, but not what I've posted above?

public extension Dictionary {
  /// Group key-value pairs by their keys.
  ///
  /// - Parameter pairs: Either `Swift.KeyValuePairs<Key, Self.Value.Element>`
  ///   or a `Sequence` with the same element type as that.
  /// - Returns: `[KeyValuePairs.Key: [KeyValuePairs.Value]]`
  init<Value, KeyValuePairs: Sequence>(grouping pairs: KeyValuePairs)
  where
    KeyValuePairs.Element == (key: Key, value: Value),
    Self.Value == [Value]
  {
    self =
      Dictionary<Key, [KeyValuePairs.Element]>(grouping: pairs, by: \.key)
      .mapValues { $0.map(\.value) }
  }

  /// Group key-value pairs by their keys.
  ///
  /// - Parameter pairs: Like `Swift.KeyValuePairs<Key, Self.Value.Element>`,
  ///   but with unlabeled elements.
  /// - Returns: `[KeyValuePairs.Key: [KeyValuePairs.Value]]`
  init<Value, KeyValuePairs: Sequence>(grouping pairs: KeyValuePairs)
  where
    KeyValuePairs.Element == (Key, Value),
    Self.Value == [Value]
  {
    self.init( grouping: pairs.map { (key: $0, value: $1) } )
  }
}

@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
Projects
None yet
Development

No branches or pull requests

3 participants