In some ways, as I mentioned in the pitch thread, this mostly feels like a bug fix to me. From my perspective as a user, there's not a great reason why the compiler shouldn't be able to find the switch
member from ToggleStyle
on S
in the .toggleStyle(.switch)
call. If it were possible to have the compiler perform member lookup on a yet-unbound generic parameter (based on the available constraints), then this feature would naturally fall out from that:
So, while I'm sympathetic to @jrose's concern about the motivation for this proposal, to me this feels like something that should "just work" given our existing rules for implicit member expressions.
This is also the reason that I oppose the restriction from the proposal:
- Require that the result type of a member declaration conforms to the declaring protocol.
As far as I can tell, there isn't any reason that we need this restriction, and we don't have such a restriction for existing implicit member chains. IMO, with the following setup,
protocol P {}
extension Int: P {}
extension P {
static var string: String { "" }
}
extension String {
static var int: Int { 0 }
}
func takesP<T: P>(_: T) { ... }
func takesInt(_: Int) { ... }
it should be perfectly valid to write both of the following:
takesP(.string.int)
takesInt(.string.int)
The type checking for the takesP
expression would conceptually proceed as:
- Look at the contextual type for
.string.int
(it'sT: P
). - Look up the
.string
member onT
(it must be theT.string
member guaranteed by theP
conformance, with typeString
). - Look up the
.int
member onString
(it has typeInt
). - The result of the member chain must be equal to the base, so the base type is
Int
, which conforms toP
, and we are done.
With the conforms-to restriction for the first member of the chain in a generic context, this feels like too much of a special case to me, so I am -0.5 on the proposal in its current form. I would be a +1 if the conforms-to restriction were lifted.