SE-0352 has the following (emphasis mine):
It's also possible to open an inout parameter. The generic function will operate on the underlying type, and can (e.g.) call mutating methods on it, but cannot change its dynamic type because it doesn't have access to the existential box:
func testOpenInOut(p: any P) { var mutableP: any P = p openInOut(&mutableP) // okay, opens to 'mutableP' and binds 'T' to its underlying type }
I wonder what does the emphasized text mean? It seems to suggest the following code is invalid, but it works well in my experiments:
func openInOut<T: P>(_ value: inout T) { }
func testOpenInOut(p: inout any P) {
openInOut(&p)
}
A complete example
protocol P {
var value: Int { get set}
}
struct S: P {
var value: Int = 1
}
func openInOut<T: P>(_ t: inout T) {
t.value = 2
}
func mutateInOutP(_ p: inout any P) {
openInOut(&p)
}
func test() {
var mutableP: any P = S()
print("p value (before running mutateInOutP()): \(mutableP.value)")
mutateInOutP(&mutableP)
print("p value (after running mutateInOutP()): \(mutableP.value)")
}
test()
// output:
// p value (before running mutateInOutP()): 1
// p value (after running mutateInOutP()): 2
I ask because I had never read about such usage on the net (I did experiments in the past and IIRC it failed to compile). However, while I read SE-0352 today, I find it works. So I'd like to confirm. This is a supported feature, right? Have anyone used it?