func cannotOpen1<T: P>(_ array: [T]) { .. } func cannotOpen2<T: P>(_ a: T, _ b: T) { ... } func cannotOpen3<T: P>(_ values: T...) { ... } struct X<T> { } func cannotOpen4<T: P>(_ x: X<T>) { } func cannotOpen5<T: P>(_ x: T, _ a: T.A) { } func cannotOpen6<T: P>(_ x: T?) { } func testCannotOpenMultiple(array: [any P], p1: any P, p2: any P, xp: X<any P>, pOpt: (any P)?) { cannotOpen1(array) // each element in the array can have a different underlying type, so we cannot open cannotOpen2(p1, p2) // p1 and p2 can have different underlying types, so there is no consistent binding for 'T' cannotOpen3(p1, p2) // similar to the case above, p1 and p2 have different types, so we cannot open them cannotOpen4(xp) // cannot open the existential in 'X<any P>' there isn't a specific value there. cannotOpen5(p1, p2.getA()) // cannot open either argument because 'T' is used in both parameters cannotOpen6(pOpt) // cannot open the existential in '(any P)?' because it might be nil, so there would not be an underlying type }
↑ structural position だと P
のオブジェクトの数が動的になるから open できない