Is this still a fixed in stone limitation? Let's say the compiler gains the ability to preserve static type information based on values. Something along these lines:
protocol P {
associatedtype Assoc
}
struct G<T>: P {
typealias Assoc = T
}
let g = G<Int>()
let num: g.Assoc = 42
Couldn't then the compiler not verify the following situation somehow? I'm not 100% sure this is valid, so I apologize up front if something in my thinking is completely wrong.
func group<T: View>(_ t: T) -> some View {
Group { t }
}
The above code is valid for regular generics, but it becomes somewhat interesting when opening existential.
let color: any View = Text("swift")
group(color)
Isn't the compiler opening the particular existential and binding the concert T type, but it doesn't really return it back to the caller of the group method. Instead it binds it to the opaque result type. The caller still doesn't know the concrete type, only the compiler knows. Theoretically T becomes Text and the result would be Group<Text>. However in regular generics func f<T: View>(_: T) -> T the result would be wrapped back to any View, but since we're not using regular generics for the return type, but the opaque one, we clearly hiding that information again.
This gets somewhat confusing to me.
group(Color.clear) // okay because `some View` hides `Group<Color>`
group(Text("swift")) // also okay
group(Text("swift") as any View) // no longer okay?!
The naive idea here is to re-pack the existential into an opaque result type, which then cannot change (contextually).
Again, I might talk nonsense here, but this is a very interesting topic, as this really feels intuitive when transforming any P to some P (as an opaque return type, not generic parameter sugar).
To further showcase my thinking, here's another example:
protocol P {}
func g<T: P>(_ t: T) -> some P { t }
struct S: P {}
struct S2: P {}
let someP_1: some P = g(S())
let someP_2: some P = g(S2())
var mutable_someP_1 = someP_1
mutable_someP_1 = someP_1 // okay
mutable_someP_1 = someP_2 // expected error
var another_mutable_someP_1: some P = someP_1
// error: cannot assign value of type 'some P' (type of 'someP_1') to type 'some P' (type of 'another_mutable_someP_1')
another_mutable_someP_1 = someP_1 // bug, or expected??
let someP_3: some P = S() as any P // is this really strictly illegal?