This compiles and runs:
struct S<T> {
var a : A
}
extension S where T == Never {
typealias A = Int
}
let v = S<Int>(a: 123)
print(v)
But should it?
(I'd expect it to be invalid since it requires Int == Never
.)
This compiles and runs:
struct S<T> {
var a : A
}
extension S where T == Never {
typealias A = Int
}
let v = S<Int>(a: 123)
print(v)
But should it?
(I'd expect it to be invalid since it requires Int == Never
.)
I think this is the same inference issue I asked here about, I smell that the where
clause is completely ignored.
struct S<T> {
var a : A
}
extension S where T == Never {
typealias A = Int
init() {
self.a = 42
}
}
let v = S()
print(v)
Ah yes, it probably is.
I started this thread because I bumped into this particular issue just now (again as it turns out, this time with Swift 5 / Xcode 10.2 and it's also in the latest dev snapshot (2019-04-10)).
I remember now that I've encountered it before and that it is related to the thread you mentioned, as well as this thread and SR-5440 (which I filed almost two years ago, but it's barely partly fixed, as the bug report is a bit too unfocused).
I've now filed the particular code example above as a separate simpler bug.
If it's the same issue I discovered in my thread then it requires a formal proposal for a change of behavior.
See my thread and also the bug report comments: [SR-10158] Associated type inference resolution ignores conditionality of extensions · Issue #52560 · apple/swift · GitHub
I'm not sure if it is the same issue, that's why I try to keep it simple:
The tiny code example in the OP (and SR-10466) as well as the following one, clearly demonstrates that the compiler accepts invalid code, something which is harmful enough by itself and shouldn't require any further motivation for fixing.
struct S<T> {
typealias Hmm = (A, B, C)
}
extension S where T == Int8 { typealias A = T }
extension S where T == Bool { typealias B = T }
extension S where T == UInt { typealias C = T }
print(S<Int>.Hmm.self) // Prints "(Int8, Bool, UInt)"
// which implies T == Int8 && T == Bool && T == UInt
// ie Int == Int8 && Int == Bool && Int == UInt
// ie something which obviously cannot be the case
// unless Swift is meant to be illogical.