Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift6のprotocol

 Swift6のprotocol

3781f49ea2c76d6ecf0c6cda46096d49?s=128

omochimetaru

May 30, 2022
Tweet

More Decks by omochimetaru

Other Decks in Programming

Transcript

  1. Swift6ͷprotocol Θ͍Θ͍swiftc #36 @omochimetaru 1

  2. protocolֵ໋͕དྷΔ • SE-0309: Unlock existentials for all protocols • SE-0328:

    Structural opaque result types • SE-0335: Introduce existential any • SE-0341: Opaque Parameter Declarations • SE-0346: Lightweight same-type requirements for primary associated types • SE-0352: Implicitly Opened Existentials • SE-0353: Constrained Existential Types 2
  3. • SE-0309: Unlock existentials for all protocols1 • SE-0328: Structural

    opaque result types2 • SE-0335: Introduce existential any3 • SE-0341: Opaque Parameter Declarations4 • SE-0346: Lightweight same-type requirements for primary associated types5 • SE-0352: Implicitly Opened Existentials6 • SE-0353: Constrained Existential Types7 7 https://github.com/apple/swift-evolution/blob/main/proposals/0353-constrained-existential-types.md 6 https://github.com/apple/swift-evolution/blob/main/proposals/0352-implicit-open-existentials.md 5 https://github.com/apple/swift-evolution/blob/main/proposals/0346-light-weight-same-type-syntax.md 4 https://github.com/apple/swift-evolution/blob/main/proposals/0341-opaque-parameters.md 3 https://github.com/apple/swift-evolution/blob/main/proposals/0335-existential-any.md 2 https://github.com/apple/swift-evolution/blob/main/proposals/0328-structural-opaque-result-types.md 1 https://github.com/apple/swift-evolution/blob/main/proposals/0309-unlock-existential-types-for-all- protocols.md 3
  4. ࠓ೔ͷ໨ඪ • ৽͍͠ݴޠػೳͷจ๏ɺҙຯɺ࣮૷Λཧղ͢Δ 4

  5. ࿩ͷྲྀΕ • ྺ࢙ • طଘػೳͷ෮श • ৽ػೳͷ঺հ 5

  6. ྺ࢙ 6

  7. Generics in Swift8 SwiftͷδΣωϦΫεͷॳظઃܭॻɻ Self Type, Associated Type, Explicit Conformance,

    Retroactive Conformance, Constraints, Existential ͳͲͷओཁͳಛ௃͕ఏএ͞Ε͍ͯΔɻ 8 https://github.com/apple/swift/blob/main/docs/Generics.rst 7
  8. Generics Manifesto9 SwiftͷδΣωϦΫεͷকདྷͷํ޲ੑΛࣔ͢จॻɻ Swift 3ͷࠒʹެ։͞Εɺ͔ͳΓઌ୺తͳػೳʹ΋ݴٴ͍ͯ͠ Δɻ Swift 4Ͱܰඍͳ΋ͷ͸࣮ݱ͞Ε͕ͨɺ ߴ౓ͳ΋ͷ͸ Swift

    5 ࣌୅ʹ͋·Γਐḿ͸ແ͔ͬͨɻ 9 https://github.com/apple/swift/blob/main/docs/GenericsManifesto.md 8
  9. Improving the UI of generics10 Swift͕ࠓޙूத͍ͯ͘͠δΣωϦΫεͷํ޲ੑΛࣔ͢ϑΥʔϥ Ϝͷॻ͖ࠐΈɻ Swift 5ͷࠒʹެ։͞ΕɺϚχϑΣετͷҰ෦ͷ಺༰Λ۷ΓԼ͛ ͍ͯΔɻ

    Swift 6ʹ޲͚ͯ͜͜Ͱݴٴ͞Εͨ಺༰͕ಋೖ͞Εͦ͏ɻ 10 https://forums.swift.org/t/improving-the-ui-of-generics/22814 9
  10. طଘػೳͷ෮श 10

  11. protocolͷػೳ 1. ܕͷػೳΛએݴ͢Δ 2. δΣωϦοΫύϥϝʔλʹ੍໿(Constraint)Λ༩͑Δ 3. ExistentialΛ࡞Δ 11

  12. ܕͷػೳΛએݴ͢Δ protocol P { associatedtype A func f(a: A) static

    func s() -> Self } struct S: P { ... } • P͸ܕ Ͱ͸ͳ͘ ͋͘·Ͱ΋ܕͷػೳͷએݴ 12
  13. associated typeͱSelf type Self type͸ػೳ্͸associated typeͱ͍ۙɻ ४ڌ(conform)͢ΔଆͰࣗ਎ΛׂΓ౰ͯΔࣄ͕ڧ͍ΒΕ͍ͯΔ͚ͩɻ protocol P {

    associatedtype CustomSelf } struct S: P { typealias CustomSelf = S } 13
  14. static member ͱ metatype static member͸metatypeʹର͢Δmemberఆٛͱଊ͑ΒΕΔɻ protocol P { associatedtype

    A static func s(a: A) -> Self } struct S: P { ... } func foo(type: P.Type) { ... } func main() { foo(type: S.self) } 14
  15. protocol P { associatedtype A static func s(a: A) ->

    Self } // ҎԼͷΑ͏ͳؾ࣋ͪ protocol PMetatype { associatedtype A associatedtype P func s(a: A) -> P } 15
  16. ੍໿Λ༩͑Δ ·੍ͣ໿Λ༩͑ͳ͍৔߹Λ֬ೝ͢Δ func foo<T>(t: T) -> T { ... }

    • ܕ <T> ʹ͍ͭͯఆٛ͞Εͨؔ਺ 16
  17. ࣮૷ ; a.foo<A>(t: A) -> A define hidden swiftcc void

    @"$s1a3foo1txx_tlF"( ; TܕͷฦΓ஋͕opaqueͳϙΠϯλҾ਺ʹͳΔ %swift.opaque* noalias nocapture sret(%swift.opaque) %0, ; TܕͷҾ਺͸opaqueͳϙΠϯλ %swift.opaque* noalias nocapture %1, ; Tͷਅͷܕ %swift.type* %T ) #0 { ... } 17
  18. Value Witness Table11 • ϝλλΠϓ(%swift.type*) ͔Β͸ Value Witness Table ͕औΓग़ͤ

    Δɻ • δΣωϦοΫͳܕ <T> ͷ஋(value)ʹର͢Δجຊૢ࡞͕ೖͬͨؔ਺ ςʔϒϧɻ • init, copy, destroy, sizeͳͲɻ • ݺͼग़͢ଆ͕ <T> ͷਅͷܕ S ͷϝλλΠϓ(ͱVWT)ΛηοτͰ౉͢ɻ 11 https://github.com/apple/swift/blob/main/include/swift/ABI/ValueWitness.def 18
  19. ੍໿Λ༩͑Δ func foo<T: P>(t: P) -> T { ... }

    • ܕ <T> ͕ P ʹ४ڌ(conform)͢Δͱ͍͏੍໿(constraint)Λ௥ Ճ 19
  20. ࣮૷ ; a.foo<A where A: a.P>(t: A) -> A define

    hidden swiftcc void @"$s1a3foo1txx_tAA1PRzlF"( ; TܕͷฦΓ஋ %swift.opaque* noalias nocapture sret(%swift.opaque) %0, ; TܕͷҾ਺ %swift.opaque* noalias nocapture %1, ; Tͷਅͷܕ %swift.type* %T, ; TͷP΁ͷ४ڌ(Protocol Witness Table) i8** %T.P ) #0 { ... } 20
  21. Protocol Witness Table12 • ܕ <T> ͕ P ʹ४ڌ͢ΔͨΊͷૢ࡞͕ೖͬͨؔ਺ςʔϒϧɻ •

    ͦͷ಺༰͸ P ͷఆٛͱ΄΅ಉ͡ܗʹͳΔɻ • ݺͼग़͢ଆ͕ <T> ͷਅͷܕ S ͷ P ΁ͷPWTΛηοτͰ౉͢ɻ 12 https://github.com/apple/swift/blob/main/docs/ABI/TypeLayout.rst#existential-container-layout 21
  22. protocol P { associatedtype A func foo(a: A) static func

    s() -> Self } struct S: P { typealias A = Int func foo(a: Int) { } static func s() -> S { S() } } 22
  23. ; protocol witness table for a.S : a.P in a

    @"$s1a1SVAA1PAAWP" = hidden global [4 x i8*] [ ; protocol conformance descriptor i8* bitcast (%swift.protocol_conformance_descriptor* @"$s1a1SVAA1PAAMc" to i8*), ; A = Swift.Int i8* getelementptr inbounds ( <{ [2 x i8], i8 }>, <{ [2 x i8], i8 }>* @"symbolic Si", i32 0, i32 0, i64 1 ), ; func foo i8* bitcast (void (%TSi*, %T1a1SV*, %swift.type*, i8**)* @"$s1a1SVAA1PA2aDP3fooAAy1AQz_tFTW" to i8*), ; static func s i8* bitcast (void (%T1a1SV*, %swift.type*, %swift.type*, i8**)* @"$s1a1SVAA1PA2aDP1sxyFZTW" to i8*) ], align 8 23
  24. associated typeʹ΋੍໿Λ༩͑Δ protocol Q {} protocol P { associatedtype A:

    Q func foo(a: A) static func s() -> Self } 24
  25. ; protocol witness table for a.S : a.P in a

    @"$s1a1SVAA1PAAWP" = hidden global [5 x i8*] [ ; protocol conformance descriptor i8* bitcast (%swift.protocol_conformance_descriptor* @"$s1a1SVAA1PAAMc" to i8*), ; SͷP४ڌʹ͓͚ΔS.AͷQ४ڌͷ৘ใ i8* getelementptr ( i8, i8* getelementptr inbounds ( <{ i8, i8, i32, i8 }>, <{ i8, i8, i32, i8 }>* @"associated conformance 1a1SVAA1PAA1AAaDP_AA1Q", i32 0, i32 0 ), i64 1 ), ; A = Swift.Int i8* getelementptr inbounds (<{ [2 x i8], i8 }>, <{ [2 x i8], i8 }>* @"symbolic Si", i32 0, i32 0, i64 1), ; func foo i8* bitcast (void (%TSi*, %T1a1SV*, %swift.type*, i8**)* @"$s1a1SVAA1PA2aDP3fooAAy1AQz_tFTW" to i8*), ; static func s i8* bitcast (void (%T1a1SV*, %swift.type*, %swift.type*, i8**)* @"$s1a1SVAA1PA2aDP1sxyFZTW" to i8*) ], align 8 25
  26. ੍໿ͷ·ͱΊ • δΣωϦοΫͳܕʹରͯ͠ߦ͑Δૢ࡞ΛϓϩτίϧͰ੍໿͢ΔࣄͰ એݴ͢Δ • ݺͼग़͢ͱ͖ͷਅͷܕ͸ίϯύΠϧ࣌ʹܾఆ͢Δ • callee͸ɺ஋ΛopaqueͳϙΠϯλɺجຊૢ࡞ͷͨΊͷVWTɺϓϩτ ίϧͱͯ͠ͷૢ࡞ͷͨΊͷPWTΛड͚औΓɺ ͦΕΒͷςʔϒϧͷؔ਺Λ௨ͯ͠஋Λૢ࡞͢Δ

    • caller͸ɺ౉ͦ͏ͱ͍ͯ͠Δਅͷܕͷઐ༻ͷVWTͱPWTΛҰॹʹ౉͢ 26
  27. Existential 27

  28. ϓϩτίϧΛܕͱͯ͠࢖͑Δ(?) protocol P { func foo() } func makeFoo() ->

    P { ... } func callFoo(_ p: P) { ... } func main() { let p: P = makeFoo() callFoo(p) } 28
  29. struct S: P {} func makeFoo() -> P { //

    S Λ P ʹ֨ೲ return S() } func callFoo(_ p: P) { // P ͔Β <T: P> ΛऔΓग़͢ p.foo() } 29
  30. Existential Container12 // ؾ࣋ͪදݱ struct PContainer { var value<T: P>:

    T func foo() { value.foo() } } • ! ϓϩτίϧΛܕͱͯ͠࢖͑Δ • " <T: P> Λอ࣋Ͱ͖ΔίϯςφܕΛ࢖͑Δ 12 https://github.com/apple/swift/blob/main/docs/ABI/TypeLayout.rst#existential-container-layout 30
  31. Existential Metatype Container func useMetatype(type: P.Type) {} func callUseMetatype(p: P)

    { useMetatype(type: type(of: p)) } func main() { useMetatype(type: S.self) callUseMetatype(p: S()) } • P ʹ४ڌ͢Δܕ T ͷϝλλΠϓͷίϯςφ 31
  32. Existential Container Metatype func useExistentialContainerMetatype(type: P.Protocol) {} func main() {

    useExistentialContainerMetatype(type: P.self) } • Existential ContainerͷϝλλΠϓ 32
  33. Existentialͷ੍ݶ 33

  34. associated type͕͋Δͱ࢖͑ͳ͍ protocol P { associatedtype A } // error:

    protocol 'P' can only be used as a generic constraint // because it has Self or associated type requirements func useP(p: P) {} 34
  35. ΋͠࢖͑ͨͱ͢Δͱ໰୊͕ੜ͡Δɻ func useP(p: P) { // P.A͕ίϯύΠϧ࣌ʹܾఆͰ͖ͳ͍ func f(a: P.A)

    {} } 35
  36. AnyܕΛ࢖ͬͯ΋contravariantͳ৔߹ʹ͏·͍͔͘ͳ͍ɻ protocol P { associatedtype A func useA(a: A) }

    struct S: P { func useA(a: Int) {} } func useP(p: P) { // useA(a: Any) ? p.useA(a: "string") } 36
  37. contravariantͳSelf type͕͋Δͱ࢖͑ͳ͍ protocol P { func foo(_ a: Self) }

    // error: protocol 'P' can only be used as a generic constraint // because it has Self or associated type requirements func useP(p: P) {} 37
  38. ΋͠࢖͑ͨͱ͢Δͱ໰୊͕ੜ͡Δɻ func makeP() -> P { ... } func useP(p:

    P) { // pͷਅͷܕͱmakeP͕ฦ͢ਅͷܕ͕ಉҰͱ͸ݶΒͳ͍ p.foo(makeP()) } 38
  39. covariantͳSelf type͸େৎ෉ protocol P { func s() -> Self func

    os() -> Self? func fs() -> () -> Self func ts() -> (Self, Self) func ffs() -> ((Self) -> Void) -> Void } // OK func useFoo(p: P) {} Self = existenal P ͱϥοϓ͢Δ͚ͩ 39
  40. Existential ͷ self conformance 40

  41. P͸PͰ͸ͳ͍ protocol P {} // error: protocol 'P' as a

    type cannot // conform to the protocol itself func useGenericP<T: P>(p: P) {} func useExistentialP(p: P) { useGenericP(p: p) } Pͷexistential͸protocol Pʹ४ڌ͍ͯ͠ͳ͍ 41
  42. associated type͕ղܾͰ͖ͳ͍ protocol P { associatedtype A } P.A ͸ਅͷܕʹΑͬͯҟͳΔ

    42
  43. contravariantͳSelf type͕ղܾͰ͖ͳ͍ protocol P { func foo(p: Self) } Self

    ͸ਅͷܕʹΑͬͯҟͳΔ 43
  44. static member͕࣮૷Ͱ͖ͳ͍ protocol P { static func s() } func

    main() { // error: static member 's' cannot be used // on protocol metatype 'P.Protocol' P.s() } 44
  45. @objc protocol͸ࣗݾ४ڌ͢Δ @objc protocol P { func foo() } func

    useGenericP<T: P>(p: T) {} func useExistentialP(p: P) { useGenericP(p: p) } • static member͕ແ͍৔߹ͷΈ • associatedtype͸ͦ΋ͦ΋ېࢭ • Self͸͋ͬͯ΋Α͍(?) 45
  46. import Foundation @objc protocol P { // contravariance Self ?

    func foo(_ p: Self) } @objc class S: NSObject, P { var x: String = "s" func foo(_ s: S) { print("expected: s, actual: \(s.s())") } func s() -> String { x } } @objc class K: NSObject, P { var y: Int = 2 func foo(_ k: K) { print("expected: 2, actual: \(k.k())") } func k() -> Int { y } } func makeSP() -> P { S() } func makeKP() -> P { K() } func useP<T: P>(p1: T, p2: T) { p1.foo(p2) } // Segmentation fault: 11 useP(p1: makeSP(), p2: makeKP()) 46
  47. Swift.Error ͸ࣗݾ४ڌ͢Δ func useGenericError<T: Error>(error: T) {} func useError(error: Error)

    { useGenericError(error: error) } • ௒ಛผ଴۰ • ϝϯό͸Կ΋ͳ͍ͷͰ໰୊͸ͳ͍ 47
  48. Existentialͷopen 48

  49. open P ͔Β <T: P> ΛऔΓग़͢ࣄΛ open ͱݺͿ func callFoo(p:

    P) { // ͜͜Ͱopen͍ͯ͠Δ p.foo() } 49
  50. extensionʹΑΔopen func proc<T: P>(_ t: T) { print(t) } func

    useP(p: P) { // error: protocol 'P' as a type cannot // conform to the protocol itself proc(p) } P ͕खݩʹ͋Δ͚Ͳ <T: P> ͕΄͍͠ࣄ͕͋Δ 50
  51. extension P { func callProc() { // let self: <Self:

    P> proc(self) } } func useP(p: P) { p.callProc() } protocol extensionͷϝιουͷself͸open͞Εͨܕ <Self: P> ʹͳͬ ͍ͯΔɻ 51
  52. existentialͷ࣮૷ 52

  53. protocol P { func foo() } func useP(p: P) {

    p.foo() } 53
  54. • Opaque Existential Containers12 struct OpaqueExistentialContainer { void *fixedSizeBuffer[3]; Metadata

    *type; WitnessTable *witnessTables[NUM_WITNESS_TABLES]; }; 12 https://github.com/apple/swift/blob/main/docs/ABI/TypeLayout.rst#existential-container-layout 54
  55. %T1b1PP = type { [24 x i8], %swift.type*, i8** }

    %__opaque_existential_type_1 = type { [24 x i8], %swift.type*, i8** } define hidden swiftcc void @"$s1b4useP1pyAA1P_p_tF"( %T1b1PP* noalias nocapture dereferenceable(40) %0 ) #0 { entry: %p.debug = alloca %T1b1PP*, align 8 %1 = bitcast %T1b1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %T1b1PP* %0, %T1b1PP** %p.debug, align 8 %2 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 1 %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 2 %5 = load i8**, i8*** %4, align 8 %6 = bitcast %T1b1PP* %0 to %__opaque_existential_type_1* %7 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1( %__opaque_existential_type_1* %6, %swift.type* %3 ) #3 %8 = getelementptr inbounds i8*, i8** %5, i32 1 %9 = load i8*, i8** %8, align 8, !invariant.load !22 %10 = bitcast i8* %9 to void (%swift.opaque*, %swift.type*, i8**)* call swiftcc void %10(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %3, i8** %5) ret void } 55
  56. ܕͷऔΓग़͠ %T1b1PP = type { [24 x i8], %swift.type*, i8**

    } %__opaque_existential_type_1 = type { [24 x i8], %swift.type*, i8** } define hidden swiftcc void @"$s1b4useP1pyAA1P_p_tF"( %T1b1PP* noalias nocapture dereferenceable(40) %0 ) #0 { entry: %p.debug = alloca %T1b1PP*, align 8 %1 = bitcast %T1b1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %T1b1PP* %0, %T1b1PP** %p.debug, align 8 %2 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 1 %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 2 %5 = load i8**, i8*** %4, align 8 %6 = bitcast %T1b1PP* %0 to %__opaque_existential_type_1* %7 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1( %__opaque_existential_type_1* %6, %swift.type* %3 ) #3 %8 = getelementptr inbounds i8*, i8** %5, i32 1 %9 = load i8*, i8** %8, align 8, !invariant.load !22 %10 = bitcast i8* %9 to void (%swift.opaque*, %swift.type*, i8**)* call swiftcc void %10(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %3, i8** %5) ret void } 56
  57. PWTͱͦͷதͷؔ਺ͷऔΓग़͠ %T1b1PP = type { [24 x i8], %swift.type*, i8**

    } %__opaque_existential_type_1 = type { [24 x i8], %swift.type*, i8** } define hidden swiftcc void @"$s1b4useP1pyAA1P_p_tF"( %T1b1PP* noalias nocapture dereferenceable(40) %0 ) #0 { entry: %p.debug = alloca %T1b1PP*, align 8 %1 = bitcast %T1b1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %T1b1PP* %0, %T1b1PP** %p.debug, align 8 %2 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 1 %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 2 %5 = load i8**, i8*** %4, align 8 %6 = bitcast %T1b1PP* %0 to %__opaque_existential_type_1* %7 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1( %__opaque_existential_type_1* %6, %swift.type* %3 ) #3 %8 = getelementptr inbounds i8*, i8** %5, i32 1 %9 = load i8*, i8** %8, align 8, !invariant.load !22 %10 = bitcast i8* %9 to void (%swift.opaque*, %swift.type*, i8**)* call swiftcc void %10(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %3, i8** %5) ret void } 57
  58. ஋ͷऔΓग़͠ %T1b1PP = type { [24 x i8], %swift.type*, i8**

    } %__opaque_existential_type_1 = type { [24 x i8], %swift.type*, i8** } define hidden swiftcc void @"$s1b4useP1pyAA1P_p_tF"( %T1b1PP* noalias nocapture dereferenceable(40) %0 ) #0 { entry: %p.debug = alloca %T1b1PP*, align 8 %1 = bitcast %T1b1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %T1b1PP* %0, %T1b1PP** %p.debug, align 8 %2 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 1 %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 2 %5 = load i8**, i8*** %4, align 8 %6 = bitcast %T1b1PP* %0 to %__opaque_existential_type_1* %7 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1( %__opaque_existential_type_1* %6, %swift.type* %3 ) #3 %8 = getelementptr inbounds i8*, i8** %5, i32 1 %9 = load i8*, i8** %8, align 8, !invariant.load !22 %10 = bitcast i8* %9 to void (%swift.opaque*, %swift.type*, i8**)* call swiftcc void %10(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %3, i8** %5) ret void } 58
  59. औΓग़ͨؔ͠਺ʹɺ஋ɺܕɺPWTΛ౉ͯ͠ݺͼग़͢ %T1b1PP = type { [24 x i8], %swift.type*, i8**

    } %__opaque_existential_type_1 = type { [24 x i8], %swift.type*, i8** } define hidden swiftcc void @"$s1b4useP1pyAA1P_p_tF"( %T1b1PP* noalias nocapture dereferenceable(40) %0 ) #0 { entry: %p.debug = alloca %T1b1PP*, align 8 %1 = bitcast %T1b1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) store %T1b1PP* %0, %T1b1PP** %p.debug, align 8 %2 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 1 %3 = load %swift.type*, %swift.type** %2, align 8 %4 = getelementptr inbounds %T1b1PP, %T1b1PP* %0, i32 0, i32 2 %5 = load i8**, i8*** %4, align 8 %6 = bitcast %T1b1PP* %0 to %__opaque_existential_type_1* %7 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1( %__opaque_existential_type_1* %6, %swift.type* %3 ) #3 %8 = getelementptr inbounds i8*, i8** %5, i32 1 %9 = load i8*, i8** %8, align 8, !invariant.load !22 %10 = bitcast i8* %9 to void (%swift.opaque*, %swift.type*, i8**)* call swiftcc void %10(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %3, i8** %5) ret void } 59
  60. Existentialͷ࣮૷ͷ·ͱΊ • Existential Container͸ɺਅͷ஋ɺͦͷܕɺPWTΛ·ͱΊͨ ΋ͷɻ • PWT͔ΒऔΓग़ͨؔ͠਺Λݺͼग़͢ܗࣜ͸ɺδΣωϦοΫؔ ਺ʹ͓͚Δ <T: P>

    ͷૢ࡞ͱશ͘ಉ͡Ͱɺopen͍ͯ͠Δͱݴ ͑Δɻ 60
  61. Existentialͷ·ͱΊ • Existential͸ <T: P> Λอ࣋͢Δίϯςφ • ϝιουݺͼग़͠ʹΑΔopenͰ <T: P>

    ΛऔΓग़ͤΔ • associated type, Self type͸varianceͷ໰୊ΛؚΉ • ࣮૷Ͱ͸ɺਅͷ஋ɺͦͷܕɺPWTΛ͍࣋ͬͯͯɺ͜Ε͸ Genericؔ਺Λݺͼग़͢ͱ͖ͷҾ਺ͱಉ͡΋ͷ 61
  62. GenericsͱExistential ͷҧ͍ 62

  63. Generic Parameter Type͸͋ΔಛఆͷܕΛҙ ຯ͢Δ func foo<T: P>(t: T) -> T

    { var u: T = t // NG // u = S() return u } <T> ͸ͦͷίϯςΩετʹ͓͚Δɺ͋ΔಛఆͷܕͰ͋Γɺ ͨͱ࣮͑ߦ࣌ʹͦ͏ͩͬͨͱͯ͠΋ɺܕνΣοΫʹ͓͍ͯ͸ S Ͱ΋ K Ͱ΋ͳ͍ɻ Ҿ਺Ͱ౉ͨ͠ t: T ͱɺͦͷίϐʔͷ u: T ΍ฦΓ஋ͷ T ͸ಉ͡ܕͰ͋Γɺ࣮ߦ࣌ʹ͓͍ͯ΋౉ͨ͠ܕ͕ฦͬͯ͘ Δɻ 63
  64. Existential Container͸ಛఆͷܕΛҙຯ͠ͳ͍ func foo(p: P) -> P { var u:

    P = p // OK u = S() return u } P ͸ <T: P> Λ֨ೲͰ͖ΔίϯςφͰɺத਎ͷܕ͸ಈతʹมԽ͠͏Δɻ Ҿ਺Ͱ౉ͨ͠ p: P ͔Βίϐʔͨ͠ u: P ʹରͯ͠ɺ طଘͷத਎ͱ͸ແؔ܎ʹ S Λ୅ೖͨ͠ΓɺͦΕΛฦͨ͠ΓͰ͖Δɻ 64
  65. Type Erasure 65

  66. Type Erasure associated typeͱࣗݾ४ڌʹରԠͨ͠existentialͷΑ͏ͳ΋ͷΛ ࣗ࡞͢Δࣄ͕͋ΓɺType Erasureͱݺ͹ΕΔɻ ඪ४ϥΠϒϥϦͰ͸ AnySequence<Element>, AnyHashable, KeyedDecodingContainer<K>

    ͳͲ͕͋Δɻ ݴޠػೳͰ͸ͳ͘୯ͳΔ࣮૷ύλʔϯͳͷͰ࣮૷͸ׂѪɻ 66
  67. Opaque Result Types 67

  68. Opaque Result Types Improving the UI of generics ͷ಺༰Λड͚ͯ Swift

    5.1 Ͱ࣮૷͞Εͨɻ protocol P { func foo() } struct S: P { func foo() {} } func makeP() -> some P { S() } 68
  69. Reverse Generics ORT͸ callee ଆ͕ܾఆ͢Δ Generic Parameter Type ͱݴ͑Δɻ Reverse

    Genericsͱ͍͏ՍۭͷߏจΛߟ͑Δͱཧղ͠΍͍͢ɻ // ORT func makeP() -> some P { S() } // Reverse Generics func makeP() -> <T: P> T { S() } 69
  70. ར༻ଆͷղऍ protocol P { associatedtype A func a() -> A

    func useA(a: A) } func main() { let p = makeP() let a = p.a() p.useA(a: a) } ORT͸ExistentialͰ͸ͳ͘GenericsͳͷͰɺassociatedtype͕࢖͑Δɻ 70
  71. makePͷݺͼग़͕͠ɺܕύϥϝʔλΛಋೖ͠ɺܾఆ͍ͯ͠Δͱ ߟ͑ΔͱΘ͔Γ΍͍͔͢΋͠Εͳ͍ɻ func main<T>() { // ↑͜ͷTͷਅͷܕ͸ // ↓͜ͷmakeP͕ܾΊΔ let

    p: T = makeP() let a: T.A = p.a() p.useA(a: a) } 71
  72. func main() { let p = makeP() let p2 =

    makeP() let a = p2.a() p.useA(a: a) } p ͱ p2 ͸ҟͳΔม਺͕ͩɺಉ͡ ʮmakeP ͷฦΓ஋ͷܕʯͳͷ Ͱɺ ಉ͡ܕͰ͋Γɺassociatedtype΋ಉ͡ܕɻ 72
  73. ܕύϥϝʔλΛॻ͘ͱ͜͏ଊ͑ΒΕΔɻ func main<T>() { // ↑͜ͷT͸ʮmakePͷฦΓ஋ͷܕʯ let p: T =

    makeP() let p2: T = makeP() let a: T.A = p2.a() p.useA(a: a) } 73
  74. ֎ଆʹύϥϝʔλ͕࿐ग़͍ͯ͠Δͷ͕ؾʹͳΔͳΒɺ͜͏ߟ͑ͯ΋ ྑ͍ɻ func main() { func body<T: P>(p: T) {

    let p: T = p let p2: T = makeP() let a: T.A = p2.a() p.useA(a: a) } body(p: makeP()) } 74
  75. ਅͷܕ͸ͦͷؔ਺͝ͱʹఆ·ΔͷͰɺͨͱ࣮͑ࡍʹ͸ಉ͡ܕʹͳΔͱͯ͠ ΋ɺҟͳΔ some P ͸ผͷܕͱͯ͠ѻΘΕΔɻ func makeP() -> some P

    { S() } func makeP2() -> some P { S() } func main() { let p = makeP() let p2 = makeP2() let a = p2.a() // error: cannot convert value of type // '(some b.P).A' (associated type of protocol 'P') // to expected argument type // '(some b.P).A' (associated type of protocol 'P') p.useA(a: a) } 75
  76. ͜Ε΋ύϥϝʔλදࣔ͢Δͱ͙͢Θ͔Δɻ func main<T1, T2>() { let p: T1 = makeP()

    let p2: T2 = makeP2() let a: T2.A = p2.a() // T2.A ͸ T1.A ͱͯ͠౉ͤͳ͍ p.useA(a: a) } 76
  77. ORTͷ࣮૷ 77

  78. // c.swift public protocol P { func foo() -> Int

    } struct S: P { func foo() -> Int { 1 } } public func makeP() -> some P { S() } // b.swift import c func main() { let p = makeP() p.foo() } 78
  79. define hidden swiftcc void @"$s1b4mainyyF"() #0 { entry: %p.debug =

    alloca i8*, align 8 %0 = bitcast i8** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1c5makePQryFQOyQo_MD") #7 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !18, !dereferenceable !19 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !18 %6 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %6) %7 = bitcast i8* %6 to %swift.opaque* store i8* %6, i8** %p.debug, align 8 call swiftcc void @"$s1c5makePQryF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %7) %8 = call swiftcc i8** @swift_getOpaqueTypeConformance(i8* undef, %swift.type_descriptor* @"$s1c5makePQryFQOMQ", i64 1) #8 %9 = getelementptr inbounds i8*, i8** %8, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !18 %11 = bitcast i8* %10 to i64 (%swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc i64 %11(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %1, i8** %8) %13 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %14 = load i8*, i8** %13, align 8, !invariant.load !18 %destroy = bitcast i8* %14 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %7, %swift.type* %1) #9 %15 = bitcast %swift.opaque* %7 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %15) ret void } 79
  80. makeP ͷฦΓ஋ͷਅͷܕͷऔΓग़͠ ; $s1c5makePQryFQOyQo_MD ---> ; demangling cache variable for

    type metadata for <<opaque return type of c.makeP() -> some>>.0 define hidden swiftcc void @"$s1b4mainyyF"() #0 { entry: %p.debug = alloca i8*, align 8 %0 = bitcast i8** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1c5makePQryFQOyQo_MD") #7 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !18, !dereferenceable !19 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !18 %6 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %6) %7 = bitcast i8* %6 to %swift.opaque* store i8* %6, i8** %p.debug, align 8 call swiftcc void @"$s1c5makePQryF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %7) %8 = call swiftcc i8** @swift_getOpaqueTypeConformance(i8* undef, %swift.type_descriptor* @"$s1c5makePQryFQOMQ", i64 1) #8 %9 = getelementptr inbounds i8*, i8** %8, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !18 %11 = bitcast i8* %10 to i64 (%swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc i64 %11(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %1, i8** %8) %13 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %14 = load i8*, i8** %13, align 8, !invariant.load !18 %destroy = bitcast i8* %14 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %7, %swift.type* %1) #9 %15 = bitcast %swift.opaque* %7 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %15) ret void } 80
  81. ਅͷܕɺVWTɺܕͷαΠζΛऔΓग़ͯ͠ϩʔΧϧม਺ΛελοΫʹ֬อ͢Δ define hidden swiftcc void @"$s1b4mainyyF"() #0 { entry: %p.debug

    = alloca i8*, align 8 %0 = bitcast i8** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1c5makePQryFQOyQo_MD") #7 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !18, !dereferenceable !19 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !18 %6 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %6) %7 = bitcast i8* %6 to %swift.opaque* store i8* %6, i8** %p.debug, align 8 call swiftcc void @"$s1c5makePQryF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %7) %8 = call swiftcc i8** @swift_getOpaqueTypeConformance(i8* undef, %swift.type_descriptor* @"$s1c5makePQryFQOMQ", i64 1) #8 %9 = getelementptr inbounds i8*, i8** %8, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !18 %11 = bitcast i8* %10 to i64 (%swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc i64 %11(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %1, i8** %8) %13 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %14 = load i8*, i8** %13, align 8, !invariant.load !18 %destroy = bitcast i8* %14 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %7, %swift.type* %1) #9 %15 = bitcast %swift.opaque* %7 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %15) ret void } 81
  82. makeP ͷݺͼग़͠ɻฦΓ஋Λୈ1Ҿ਺ͷopaque pointerͰड͚औΔɻ define hidden swiftcc void @"$s1b4mainyyF"() #0 {

    entry: %p.debug = alloca i8*, align 8 %0 = bitcast i8** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1c5makePQryFQOyQo_MD") #7 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !18, !dereferenceable !19 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !18 %6 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %6) %7 = bitcast i8* %6 to %swift.opaque* store i8* %6, i8** %p.debug, align 8 call swiftcc void @"$s1c5makePQryF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %7) %8 = call swiftcc i8** @swift_getOpaqueTypeConformance(i8* undef, %swift.type_descriptor* @"$s1c5makePQryFQOMQ", i64 1) #8 %9 = getelementptr inbounds i8*, i8** %8, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !18 %11 = bitcast i8* %10 to i64 (%swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc i64 %11(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %1, i8** %8) %13 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %14 = load i8*, i8** %13, align 8, !invariant.load !18 %destroy = bitcast i8* %14 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %7, %swift.type* %1) #9 %15 = bitcast %swift.opaque* %7 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %15) ret void } 82
  83. ਅͷܕͷ P ͷ PWT Λऔಘ ; $s1c5makePQryFQOMQ ---> opaque type

    descriptor for <<opaque return type of c.makeP() -> some>> define hidden swiftcc void @"$s1b4mainyyF"() #0 { entry: %p.debug = alloca i8*, align 8 %0 = bitcast i8** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1c5makePQryFQOyQo_MD") #7 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !18, !dereferenceable !19 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !18 %6 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %6) %7 = bitcast i8* %6 to %swift.opaque* store i8* %6, i8** %p.debug, align 8 call swiftcc void @"$s1c5makePQryF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %7) %8 = call swiftcc i8** @swift_getOpaqueTypeConformance(i8* undef, %swift.type_descriptor* @"$s1c5makePQryFQOMQ", i64 1) #8 %9 = getelementptr inbounds i8*, i8** %8, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !18 %11 = bitcast i8* %10 to i64 (%swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc i64 %11(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %1, i8** %8) %13 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %14 = load i8*, i8** %13, align 8, !invariant.load !18 %destroy = bitcast i8* %14 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %7, %swift.type* %1) #9 %15 = bitcast %swift.opaque* %7 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %15) ret void } 83
  84. PWT͔ΒऔΓग़ͨؔ͠਺Λݺͼग़͢ define hidden swiftcc void @"$s1b4mainyyF"() #0 { entry: %p.debug

    = alloca i8*, align 8 %0 = bitcast i8** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1c5makePQryFQOyQo_MD") #7 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !18, !dereferenceable !19 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !18 %6 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %6) %7 = bitcast i8* %6 to %swift.opaque* store i8* %6, i8** %p.debug, align 8 call swiftcc void @"$s1c5makePQryF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %7) %8 = call swiftcc i8** @swift_getOpaqueTypeConformance(i8* undef, %swift.type_descriptor* @"$s1c5makePQryFQOMQ", i64 1) #8 %9 = getelementptr inbounds i8*, i8** %8, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !18 %11 = bitcast i8* %10 to i64 (%swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc i64 %11(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %1, i8** %8) %13 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %14 = load i8*, i8** %13, align 8, !invariant.load !18 %destroy = bitcast i8* %14 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %7, %swift.type* %1) #9 %15 = bitcast %swift.opaque* %7 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %15) ret void } 84
  85. VWTͷdestroyͰϩʔΧϧม਺Λ࡟আ͢Δ define hidden swiftcc void @"$s1b4mainyyF"() #0 { entry: %p.debug

    = alloca i8*, align 8 %0 = bitcast i8** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1c5makePQryFQOyQo_MD") #7 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !18, !dereferenceable !19 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !18 %6 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %6) %7 = bitcast i8* %6 to %swift.opaque* store i8* %6, i8** %p.debug, align 8 call swiftcc void @"$s1c5makePQryF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %7) %8 = call swiftcc i8** @swift_getOpaqueTypeConformance(i8* undef, %swift.type_descriptor* @"$s1c5makePQryFQOMQ", i64 1) #8 %9 = getelementptr inbounds i8*, i8** %8, i32 1 %10 = load i8*, i8** %9, align 8, !invariant.load !18 %11 = bitcast i8* %10 to i64 (%swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc i64 %11(%swift.opaque* noalias nocapture swiftself %7, %swift.type* %1, i8** %8) %13 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %14 = load i8*, i8** %13, align 8, !invariant.load !18 %destroy = bitcast i8* %14 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %7, %swift.type* %1) #9 %15 = bitcast %swift.opaque* %7 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %15) ret void } 85
  86. __swift_instantiateConcreteTypeFromMangledName ͸ swift_getTypeByMangledNameInContext ͷΩϟογϡ෇͖ϥούʔɻ define linkonce_odr hidden %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32,

    i32 }* %0) #1 { entry: %1 = bitcast { i32, i32 }* %0 to i64* %2 = load atomic i64, i64* %1 monotonic, align 8 %3 = icmp slt i64 %2, 0 %4 = call i1 @llvm.expect.i1(i1 %3, i1 false) br i1 %4, label %8, label %5 5: ; preds = %8, %entry %6 = phi i64 [ %2, %entry ], [ %17, %8 ] %7 = inttoptr i64 %6 to %swift.type* ret %swift.type* %7 8: ; preds = %entry %9 = ashr i64 %2, 32 %10 = sub i64 0, %9 %11 = trunc i64 %2 to i32 %12 = sext i32 %11 to i64 %13 = ptrtoint { i32, i32 }* %0 to i64 %14 = add i64 %13, %12 %15 = inttoptr i64 %14 to i8* %16 = call swiftcc %swift.type* @swift_getTypeByMangledNameInContext(i8* %15, i64 %10, %swift.type_descriptor* null, i8** null) #7 %17 = ptrtoint %swift.type* %16 to i64 store atomic i64 %17, i64* %1 monotonic, align 8 br label %5 } 86
  87. ORTͷ࣮૷ͷ·ͱΊ • ΠϯλʔϑΣʔε͸Genericsͱಉ͡opaque pointerΛ࢖͏ ͕ɺਅͷܕ΍PWT͸౉͞ͳ͍ɻ • ORTͷਅͷܕͱPWT͸ɺͦͷdescriptorΛϥϯλΠϜؔ਺ʹ ౉͢͜ͱͰɺݺͼग़͠ଆͰऔಘͰ͖ΔΑ͏ʹͳ͍ͬͯΔɻ 87

  88. ৽ػೳ 88

  89. SE-0335: Introduce existential any protocol P {} func useP(_ p:

    any P) {} Existentialͷܕ໊͕ any P ʹͳͬͨࣄͰɺ<T: P> ͱผͷ֓೦Ͱ ͋Δ͜ͱ͕௚ײతʹΘ͔Γ΍͘͢ͳΔ 89
  90. Any ͱ AnyObject ͸ෆཁ func useAny(_ a: Any) {} func

    useAnyObject(_ a: AnyObject) {} ͢Ͱʹ໊લʹ Any ͷจࣈ͕෇͍͍ͯͯΘ͔Γ΍͍͢ 90
  91. Existential Metatype Container func useMetatype(_ p: any P.Type) {} useMetatype(S.self)

    P ʹ४ڌ͢ΔܕͷϝλλΠϓͷܕ͸ any P.Type ͱදه͢Δɻ any ͸ P.Type ʹର͔͔͍ͯͬͯ͠Δɻ ैདྷ͸ P.Type ͱॻ͍͍ͯͨɻ 91
  92. Existential Container Metatype func useExistentialMetatype(_ p: (any P).Type) {} useExistentialMetatype((any

    P).self) Existential ContainerͷϝλλΠϓ͸ (any P).Type ͱදه͢ Δɻ ஋͸ (any P).self Ͱੜ੒Ͱ͖Δɻ ैདྷͳ P.Protocol ͱ P.self ͱॻ͍͍ͯͨɻ 92
  93. Protocol Composition func useExistential(_ e: any P & Q) {}

    func useMetatype(_ t: any (P & Q).Type) {} func useExistentialMetatype(_ t: (any P & Q).Type) {} useExistential(S()) useMetatype(S.self) useExistentialMetatype((any P & Q).self) 93
  94. SE-0309: Unlock existentials for all protocols protocol P { associatedtype

    A } func useP(_ p: any P) {} ͋ΒΏΔϓϩτίϧ͕ Existential Λߏ੒Ͱ͖ΔΑ͏ʹͳͬͨ 94
  95. contravariantͳassociated type͸࢖͑ͳ͍ protocol P { associatedtype A func a() ->

    A func useA(_ a: A) } func useP(_ p: any P) { // ok p.a() // error: member 'useA' cannot be used on value of type 'any P'; // consider using a generic constraint instead p.useA(1) } 95
  96. contravariantͳSelf type͸࢖͑ͳ͍ protocol P { func p() -> Self func

    useP(_ p: Self) } func useP(_ p: any P) { // ok p.p() // error: member 'useP' cannot be used on value of type 'any P'; // consider using a generic constraint instead p.useP(p) } 96
  97. covariantͳϝϯό͸upper boundʹͳΔ protocol BP {} protocol P { associatedtype A

    associatedtype B: BP func p() -> Self func a() -> A func b() -> B } func useP(_ p: any P) { let p2: any P = p.p() let a: Any = p.a() let b: any BP = p.b() } ͜ͷ upper boundͳexistentialܕͷੜ੒͸શ͘৽͍͠ϩδοΫ 97
  98. ෳࡶͳcovariance protocol P { func passSelf(_ f: (Self) -> Void)

    } func useP(_ p: any P) { p.passSelf { (p: any P) in } } 98
  99. ܧঝ࣌ͷconstraintʹΑΔܕͷݻఆ protocol P { associatedtype A func a() -> A

    func useA(_ a: A) } protocol Q: P where Self.A == Int {} func useQ(q: any Q) { let a: Int = q.a() q.useA(1) } 99
  100. compositionʹΑΔܕͷݻఆ protocol P { associatedtype A } class C: P

    { typealias A = Int } protocol Q: P { func a() -> A func useA(_ a: A) } func useQ(q: any Q & C) { let a: Int = q.a() q.useA(1) } 100
  101. Existentialͷ upper boundม׵ͷ࣮૷ 101

  102. protocol BP {} protocol P { associatedtype A associatedtype B:

    BP func p() -> Self func a() -> A func b() -> B } func callP(_ p: any P) -> any P { p.p() } 102
  103. Existential Containerͷܗ͸ಛʹมΘΒͳ͍ %T1d1PP = type { [24 x i8], %swift.type*,

    i8** } 103
  104. define hidden swiftcc void @"$s1d5callPyAA1P_pAaC_pF"( %T1d1PP* noalias nocapture sret(%T1d1PP) %0,

    %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 4 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 1 store %swift.type* %4, %swift.type** %12, align 8 %13 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 2 store i8** %6, i8*** %13, align 8 %14 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %15 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %16 = bitcast %T1d1PP* %0 to %__opaque_existential_type_1* %17 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_1(%__opaque_existential_type_1* %16) #4 call swiftcc void %11( %swift.opaque* noalias nocapture sret(%swift.opaque) %17, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6 ) ret void } 104
  105. Ҿ਺ͷopenͱwitnessϝιουऔΓग़͠ define hidden swiftcc void @"$s1d5callPyAA1P_pAaC_pF"( %T1d1PP* noalias nocapture sret(%T1d1PP)

    %0, %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 4 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 1 store %swift.type* %4, %swift.type** %12, align 8 %13 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 2 store i8** %6, i8*** %13, align 8 %14 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %15 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %16 = bitcast %T1d1PP* %0 to %__opaque_existential_type_1* %17 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_1(%__opaque_existential_type_1* %16) #4 call swiftcc void %11( %swift.opaque* noalias nocapture sret(%swift.opaque) %17, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6 ) ret void } 105
  106. ฦΓ஋ͷ any P ΁ͷܕͱwitness tableͷॻ͖ࠐΈ define hidden swiftcc void @"$s1d5callPyAA1P_pAaC_pF"(

    %T1d1PP* noalias nocapture sret(%T1d1PP) %0, %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 4 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 1 store %swift.type* %4, %swift.type** %12, align 8 %13 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 2 store i8** %6, i8*** %13, align 8 %14 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %15 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %16 = bitcast %T1d1PP* %0 to %__opaque_existential_type_1* %17 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_1(%__opaque_existential_type_1* %16) #4 call swiftcc void %11( %swift.opaque* noalias nocapture sret(%swift.opaque) %17, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6 ) ret void } 106
  107. ฦΓ஋ any P ͷ஋෦෼ͷϙΠϯλͷऔΓग़͠ define hidden swiftcc void @"$s1d5callPyAA1P_pAaC_pF"( %T1d1PP*

    noalias nocapture sret(%T1d1PP) %0, %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 4 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 1 store %swift.type* %4, %swift.type** %12, align 8 %13 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 2 store i8** %6, i8*** %13, align 8 %14 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %15 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %16 = bitcast %T1d1PP* %0 to %__opaque_existential_type_1* %17 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_1(%__opaque_existential_type_1* %16) #4 call swiftcc void %11( %swift.opaque* noalias nocapture sret(%swift.opaque) %17, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6 ) ret void } 107
  108. witnessϝιουͷpͷݺͼग़͠ define hidden swiftcc void @"$s1d5callPyAA1P_pAaC_pF"( %T1d1PP* noalias nocapture sret(%T1d1PP)

    %0, %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 4 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 1 store %swift.type* %4, %swift.type** %12, align 8 %13 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 2 store i8** %6, i8*** %13, align 8 %14 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %15 = getelementptr inbounds %T1d1PP, %T1d1PP* %0, i32 0, i32 0 %16 = bitcast %T1d1PP* %0 to %__opaque_existential_type_1* %17 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_1(%__opaque_existential_type_1* %16) #4 call swiftcc void %11( %swift.opaque* noalias nocapture sret(%swift.opaque) %17, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6 ) ret void } 108
  109. func callA(_ p: any P) -> Any { p.a() }

    109
  110. define hidden swiftcc void @"$s1d5callAyypAA1P_pF"( %Any* noalias nocapture sret(%Any) %0,

    %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 5 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %6, %swift.type* %4, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 10 ) ) #9 %13 = extractvalue %swift.metadata_response %12, 0 %14 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 1 store %swift.type* %13, %swift.type** %14, align 8 %15 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %16 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %17 = bitcast %Any* %0 to %__opaque_existential_type_0* %18 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_0(%__opaque_existential_type_0* %17) #4 call swiftcc void %11(%swift.opaque* noalias nocapture sret(%swift.opaque) %18, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6) ret void } 110
  111. ฦΓ஋ͷ Any ͸ witness table Λ࣋ͨͳ͍existentialͷܗΛ͍ͯ͠Δ %Any = type {

    [24 x i8], %swift.type* } define hidden swiftcc void @"$s1d5callAyypAA1P_pF"( %Any* noalias nocapture sret(%Any) %0, %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 5 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %6, %swift.type* %4, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 10 ) ) #9 %13 = extractvalue %swift.metadata_response %12, 0 %14 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 1 store %swift.type* %13, %swift.type** %14, align 8 %15 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %16 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %17 = bitcast %Any* %0 to %__opaque_existential_type_0* %18 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_0(%__opaque_existential_type_0* %17) #4 call swiftcc void %11(%swift.opaque* noalias nocapture sret(%swift.opaque) %18, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6) ret void } 111
  112. Ҿ਺ͷ any P ͔ΒਅͷܕͱWTͷऔΓग़͠ define hidden swiftcc void @"$s1d5callAyypAA1P_pF"( %Any*

    noalias nocapture sret(%Any) %0, %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 5 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %6, %swift.type* %4, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 10 ) ) #9 %13 = extractvalue %swift.metadata_response %12, 0 %14 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 1 store %swift.type* %13, %swift.type** %14, align 8 %15 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %16 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %17 = bitcast %Any* %0 to %__opaque_existential_type_0* %18 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_0(%__opaque_existential_type_0* %17) #4 call swiftcc void %11(%swift.opaque* noalias nocapture sret(%swift.opaque) %18, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6) ret void } 112
  113. ϥϯλΠϜؔ਺Ͱ associatedtype A ͷਅͷܕΛऔΓग़͠ define hidden swiftcc void @"$s1d5callAyypAA1P_pF"( %Any*

    noalias nocapture sret(%Any) %0, %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 5 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %6, %swift.type* %4, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 10 ) ) #9 %13 = extractvalue %swift.metadata_response %12, 0 %14 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 1 store %swift.type* %13, %swift.type** %14, align 8 %15 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %16 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %17 = bitcast %Any* %0 to %__opaque_existential_type_0* %18 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_0(%__opaque_existential_type_0* %17) #4 call swiftcc void %11(%swift.opaque* noalias nocapture sret(%swift.opaque) %18, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6) ret void } 113
  114. औΓग़ͨ͠ܕΛฦΓ஋ͷܕͱͯ͠ηοτɺଞಉ༷ define hidden swiftcc void @"$s1d5callAyypAA1P_pF"( %Any* noalias nocapture sret(%Any)

    %0, %T1d1PP* noalias nocapture dereferenceable(40) %1 ) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 5 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %6, %swift.type* %4, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 10 ) ) #9 %13 = extractvalue %swift.metadata_response %12, 0 %14 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 1 store %swift.type* %13, %swift.type** %14, align 8 %15 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %16 = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0 %17 = bitcast %Any* %0 to %__opaque_existential_type_0* %18 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_0(%__opaque_existential_type_0* %17) #4 call swiftcc void %11(%swift.opaque* noalias nocapture sret(%swift.opaque) %18, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6) ret void } 114
  115. func callB(_ p: any P) -> any BP { p.b()

    } 115
  116. define hidden swiftcc void @"$s1d5callByAA2BP_pAA1P_pF"( %T1d2BPP* noalias nocapture sret(%T1d2BPP) %0,

    %T1d1PP* noalias nocapture dereferenceable(40) %1) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 6 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %6, %swift.type* %4, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 11 ) ) #9 %13 = extractvalue %swift.metadata_response %12, 0 %14 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 1 store %swift.type* %13, %swift.type** %14, align 8 %15 = call swiftcc i8** @swift_getAssociatedConformanceWitness( i8** %6, %swift.type* %4, %swift.type* %13, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ) ) #9 %16 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 2 store i8** %15, i8*** %16, align 8 %17 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 0 %18 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 0 %19 = bitcast %T1d2BPP* %0 to %__opaque_existential_type_1* %20 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_1(%__opaque_existential_type_1* %19) #4 call swiftcc void %11( %swift.opaque* noalias nocapture sret(%swift.opaque) %20, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6 ) ret void } 116
  117. ϥϯλΠϜؔ਺Ͱ associatedtype B ͷਅͷܕͷऔΓग़͠ define hidden swiftcc void @"$s1d5callByAA2BP_pAA1P_pF"( %T1d2BPP*

    noalias nocapture sret(%T1d2BPP) %0, %T1d1PP* noalias nocapture dereferenceable(40) %1) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 6 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %6, %swift.type* %4, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 11 ) ) #9 %13 = extractvalue %swift.metadata_response %12, 0 %14 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 1 store %swift.type* %13, %swift.type** %14, align 8 %15 = call swiftcc i8** @swift_getAssociatedConformanceWitness( i8** %6, %swift.type* %4, %swift.type* %13, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ) ) #9 %16 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 2 store i8** %15, i8*** %16, align 8 %17 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 0 %18 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 0 %19 = bitcast %T1d2BPP* %0 to %__opaque_existential_type_1* %20 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_1(%__opaque_existential_type_1* %19) #4 call swiftcc void %11( %swift.opaque* noalias nocapture sret(%swift.opaque) %20, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6 ) ret void } 117
  118. ϥϯλΠϜؔ਺Ͱ associatedtype B ͷ PB ͷ PWT ΛऔΓग़͠ɺҎԼಉ༷ define hidden

    swiftcc void @"$s1d5callByAA2BP_pAA1P_pF"( %T1d2BPP* noalias nocapture sret(%T1d2BPP) %0, %T1d1PP* noalias nocapture dereferenceable(40) %1) #0 { entry: %p.debug = alloca %T1d1PP*, align 8 %2 = bitcast %T1d1PP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %2, i8 0, i64 8, i1 false) store %T1d1PP* %1, %T1d1PP** %p.debug, align 8 %3 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 1 %4 = load %swift.type*, %swift.type** %3, align 8 %5 = getelementptr inbounds %T1d1PP, %T1d1PP* %1, i32 0, i32 2 %6 = load i8**, i8*** %5, align 8 %7 = bitcast %T1d1PP* %1 to %__opaque_existential_type_1* %8 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %7, %swift.type* %4) #4 %9 = getelementptr inbounds i8*, i8** %6, i32 6 %10 = load i8*, i8** %9, align 8, !invariant.load !39 %11 = bitcast i8* %10 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %12 = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness( i64 0, i8** %6, %swift.type* %4, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 11 ) ) #9 %13 = extractvalue %swift.metadata_response %12, 0 %14 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 1 store %swift.type* %13, %swift.type** %14, align 8 %15 = call swiftcc i8** @swift_getAssociatedConformanceWitness( i8** %6, %swift.type* %4, %swift.type* %13, %swift.protocol_requirement* getelementptr ( %swift.protocol_requirement, %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ), i32 -1 ), %swift.protocol_requirement* getelementptr inbounds ( <{ ... }>, <{ ... }>* @"$s1d1PMp", i32 0, i32 9 ) ) #9 %16 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 2 store i8** %15, i8*** %16, align 8 %17 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 0 %18 = getelementptr inbounds %T1d2BPP, %T1d2BPP* %0, i32 0, i32 0 %19 = bitcast %T1d2BPP* %0 to %__opaque_existential_type_1* %20 = call %swift.opaque* @__swift_allocate_boxed_opaque_existential_1(%__opaque_existential_type_1* %19) #4 call swiftcc void %11( %swift.opaque* noalias nocapture sret(%swift.opaque) %20, %swift.opaque* noalias nocapture swiftself %8, %swift.type* %4, i8** %6 ) ret void } 118
  119. Existentialͷ੍ݶഇࢭͷ·ͱΊ • ͲΜͳprotocolͰ΋existentialʹ࢖͑ΔΑ͏ʹͳͬͨ • ࠔΔvarianceͷϝϯό͸࢖༻ෆೳʹͨ͠ • covarianceͰ͸upper boundʹแΜͩ • existentialͷܕͷ෦෼ΛઌʹຒΊΔͱɺ஋ͷ෦෼͸௨ৗͷ

    GenericsͱABIޓ׵ੑ͕͋Δ • associated typeͷ৘ใ͸ϥϯλΠϜؔ਺ͰऔΓग़ͤΔ 119
  120. SE-0328: Structural opaque result types func ortOptional() -> (some P)?

    { S() } func ortTuple() -> (some P, some Q) { (S(), S()) } func ortArray() -> [some P] { [S(), S()] } func ortGeneric() -> C<some P> { C<S>() } some ͕ฦΓ஋ͷܕύϥϝʔλ෦෼Ͱ࢖͑Δ 120
  121. some P͸͋ΔҰͭͷܕΛҙຯ͢Δ func ortArray() -> [some P] { ... }

    // ؾ࣋ͪ func ortArray() -> <T: P> [T] { ... } ഑ྻͰ͋Ε͹ɺཁૉͷܕ͸શͯಉҰɻ 121
  122. ࣮૷࿙Ε13 func ortFunc() -> () -> some P { {

    S() } } ఏҊॻʹΑΔͱ͜Ε΋Ͱ͖Δ͸ͣΒ͍͠ 13 https://github.com/apple/swift/blob/main/test/type/opaque_return_structural.swift 122
  123. ฦؔ͢਺ͷύϥϝʔλ෦෼͸ବ໨ func ortFuncParam() -> (some P) -> () { ...

    } callerଆͰऔಘͨؔ͠਺͕ड͚औΔ some P Λ࡞Δํ๏͕ແ͍ɻ 14 14 https://github.com/apple/swift-evolution/blob/main/proposals/0341-opaque-parameters.md#opaque- parameters-in-consuming-positions-of-function-types 123
  124. S-ORTͷ࣮૷ 124

  125. func ortTuple() -> (some P, some Q) { (S(), S())

    } func main() { let t = ortTuple() } 125
  126. SILΛݟ͓ͯ͘ // ortTuple() sil @$s1e8ortTupleQr_QR_tyF : $@convention(thin) @substituted <τ_0_0, τ_0_1>

    () -> (@out τ_0_0, @out τ_0_1) for < @_opaqueReturnTypeOf("$s1e8ortTupleQr_QR_tyF", 0) __, @_opaqueReturnTypeOf("$s1e8ortTupleQr_QR_tyF", 1) __ > { ... } 126
  127. define hidden swiftcc void @"$s1f4mainyyF"() #0 { entry: %t.debug =

    alloca i8*, align 8 %0 = bitcast i8** %t.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD" ) #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %t = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %t) %6 = bitcast i8* %t to <{}>* store i8* %t, i8** %t.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* call swiftcc void @"$s1e8ortTupleQr_QR_tyF"(%swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1) %11 = call <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %6) %12 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 127
  128. ฦΓ஋ͷϝλλΠϓΛऔಘ ; $s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD ---> ; demangling cache variable for type

    metadata for ( ; <<opaque return type of e.ortTuple() -> (some, some)>>.0, ; <<opaque return type of e.ortTuple() -> (some, some)>>.1 ; ) define hidden swiftcc void @"$s1f4mainyyF"() #0 { entry: %t.debug = alloca i8*, align 8 %0 = bitcast i8** %t.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD" ) #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %t = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %t) %6 = bitcast i8* %t to <{}>* store i8* %t, i8** %t.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* call swiftcc void @"$s1e8ortTupleQr_QR_tyF"(%swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1) %11 = call <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %6) %12 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 128
  129. VWTΛऔΓग़ͯ͠ฦΓ஋ͷλϓϧͷϝϞϦྖҬΛ֬อ define hidden swiftcc void @"$s1f4mainyyF"() #0 { entry: %t.debug

    = alloca i8*, align 8 %0 = bitcast i8** %t.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD" ) #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %t = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %t) %6 = bitcast i8* %t to <{}>* store i8* %t, i8** %t.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* call swiftcc void @"$s1e8ortTupleQr_QR_tyF"(%swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1) %11 = call <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %6) %12 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 129
  130. λϓϧͷ0൪ཁૉͷϙΠϯλΛऔಘ define hidden swiftcc void @"$s1f4mainyyF"() #0 { entry: %t.debug

    = alloca i8*, align 8 %0 = bitcast i8** %t.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD" ) #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %t = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %t) %6 = bitcast i8* %t to <{}>* store i8* %t, i8** %t.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* call swiftcc void @"$s1e8ortTupleQr_QR_tyF"(%swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1) %11 = call <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %6) %12 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 130
  131. λϓϧͷ1൪ཁૉͷΦϑηοτΛऔಘͯ͠ɺϙΠϯλΛܭࢉ define hidden swiftcc void @"$s1f4mainyyF"() #0 { entry: %t.debug

    = alloca i8*, align 8 %0 = bitcast i8** %t.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD" ) #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %t = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %t) %6 = bitcast i8* %t to <{}>* store i8* %t, i8** %t.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* call swiftcc void @"$s1e8ortTupleQr_QR_tyF"(%swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1) %11 = call <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %6) %12 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 131
  132. λϓϧͷ2ͭͷཁૉͷϙΠϯλΛҾ਺Ͱ౉ͯ͠ฦΓ஋Λऔಘ define hidden swiftcc void @"$s1f4mainyyF"() #0 { entry: %t.debug

    = alloca i8*, align 8 %0 = bitcast i8** %t.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD" ) #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %t = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %t) %6 = bitcast i8* %t to <{}>* store i8* %t, i8** %t.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* call swiftcc void @"$s1e8ortTupleQr_QR_tyF"(%swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1) %11 = call <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %6) %12 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 132
  133. औಘͨ͠λϓϧΛ࡟আ ; $s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh ---> ; outlined destroy of ( ;

    <<opaque return type of e.ortTuple() -> (some, some)>>.0, ; <<opaque return type of e.ortTuple() -> (some, some)>>.1 ; ) define hidden swiftcc void @"$s1f4mainyyF"() #0 { entry: %t.debug = alloca i8*, align 8 %0 = bitcast i8** %t.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD" ) #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %t = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %t) %6 = bitcast i8* %t to <{}>* store i8* %t, i8** %t.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* call swiftcc void @"$s1e8ortTupleQr_QR_tyF"(%swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1) %11 = call <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %6) %12 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %12) ret void } 133
  134. ࡟আؔ਺ define linkonce_odr hidden <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %0) #7 { entry:

    %.elt = bitcast <{}>* %0 to %swift.opaque* %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo_MD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %5 = load i8*, i8** %4, align 8, !invariant.load !19 %destroy = bitcast i8* %5 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %.elt, %swift.type* %1) #9 %6 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD") #8 %7 = bitcast %swift.type* %6 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %0 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo0_MD") #8 %12 = bitcast %swift.type* %11 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses2 = load i8**, i8*** %13, align 8, !invariant.load !19, !dereferenceable !20 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses2, i32 1 %15 = load i8*, i8** %14, align 8, !invariant.load !19 %destroy3 = bitcast i8* %15 to void (%swift.opaque*, %swift.type*)* call void %destroy3(%swift.opaque* noalias %.elt1, %swift.type* %11) #9 ret <{}>* %0 } 134
  135. ฦΓ஋ͷλϓϧͷ0൪ཁૉͷܕΛऔಘ define linkonce_odr hidden <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %0) #7 { entry:

    %.elt = bitcast <{}>* %0 to %swift.opaque* %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo_MD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %5 = load i8*, i8** %4, align 8, !invariant.load !19 %destroy = bitcast i8* %5 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %.elt, %swift.type* %1) #9 %6 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD") #8 %7 = bitcast %swift.type* %6 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %0 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo0_MD") #8 %12 = bitcast %swift.type* %11 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses2 = load i8**, i8*** %13, align 8, !invariant.load !19, !dereferenceable !20 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses2, i32 1 %15 = load i8*, i8** %14, align 8, !invariant.load !19 %destroy3 = bitcast i8* %15 to void (%swift.opaque*, %swift.type*)* call void %destroy3(%swift.opaque* noalias %.elt1, %swift.type* %11) #9 ret <{}>* %0 } 135
  136. VWTΛ࢖ͬͯ0൪ཁૉΛ࡟আ define linkonce_odr hidden <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %0) #7 { entry:

    %.elt = bitcast <{}>* %0 to %swift.opaque* %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo_MD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %5 = load i8*, i8** %4, align 8, !invariant.load !19 %destroy = bitcast i8* %5 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %.elt, %swift.type* %1) #9 %6 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD") #8 %7 = bitcast %swift.type* %6 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %0 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo0_MD") #8 %12 = bitcast %swift.type* %11 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses2 = load i8**, i8*** %13, align 8, !invariant.load !19, !dereferenceable !20 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses2, i32 1 %15 = load i8*, i8** %14, align 8, !invariant.load !19 %destroy3 = bitcast i8* %15 to void (%swift.opaque*, %swift.type*)* call void %destroy3(%swift.opaque* noalias %.elt1, %swift.type* %11) #9 ret <{}>* %0 } 136
  137. λϓϧͷܕΛऔಘ define linkonce_odr hidden <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %0) #7 { entry:

    %.elt = bitcast <{}>* %0 to %swift.opaque* %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo_MD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %5 = load i8*, i8** %4, align 8, !invariant.load !19 %destroy = bitcast i8* %5 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %.elt, %swift.type* %1) #9 %6 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD") #8 %7 = bitcast %swift.type* %6 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %0 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo0_MD") #8 %12 = bitcast %swift.type* %11 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses2 = load i8**, i8*** %13, align 8, !invariant.load !19, !dereferenceable !20 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses2, i32 1 %15 = load i8*, i8** %14, align 8, !invariant.load !19 %destroy3 = bitcast i8* %15 to void (%swift.opaque*, %swift.type*)* call void %destroy3(%swift.opaque* noalias %.elt1, %swift.type* %11) #9 ret <{}>* %0 } 137
  138. λϓϧͷୈ1ཁૉͷϙΠϯλΛऔಘ define linkonce_odr hidden <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %0) #7 { entry:

    %.elt = bitcast <{}>* %0 to %swift.opaque* %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo_MD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %5 = load i8*, i8** %4, align 8, !invariant.load !19 %destroy = bitcast i8* %5 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %.elt, %swift.type* %1) #9 %6 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD") #8 %7 = bitcast %swift.type* %6 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %0 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo0_MD") #8 %12 = bitcast %swift.type* %11 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses2 = load i8**, i8*** %13, align 8, !invariant.load !19, !dereferenceable !20 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses2, i32 1 %15 = load i8*, i8** %14, align 8, !invariant.load !19 %destroy3 = bitcast i8* %15 to void (%swift.opaque*, %swift.type*)* call void %destroy3(%swift.opaque* noalias %.elt1, %swift.type* %11) #9 ret <{}>* %0 } 138
  139. λϓϧͷୈ1ཁૉͷܕΛऔಘ define linkonce_odr hidden <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %0) #7 { entry:

    %.elt = bitcast <{}>* %0 to %swift.opaque* %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo_MD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %5 = load i8*, i8** %4, align 8, !invariant.load !19 %destroy = bitcast i8* %5 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %.elt, %swift.type* %1) #9 %6 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD") #8 %7 = bitcast %swift.type* %6 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %0 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo0_MD") #8 %12 = bitcast %swift.type* %11 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses2 = load i8**, i8*** %13, align 8, !invariant.load !19, !dereferenceable !20 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses2, i32 1 %15 = load i8*, i8** %14, align 8, !invariant.load !19 %destroy3 = bitcast i8* %15 to void (%swift.opaque*, %swift.type*)* call void %destroy3(%swift.opaque* noalias %.elt1, %swift.type* %11) #9 ret <{}>* %0 } 139
  140. VWTΛ࢖ͬͯλϓϧͷୈ1ཁૉΛ࡟আ define linkonce_odr hidden <{}>* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tWOh"(<{}>* %0) #7 { entry:

    %.elt = bitcast <{}>* %0 to %swift.opaque* %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo_MD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 1 %5 = load i8*, i8** %4, align 8, !invariant.load !19 %destroy = bitcast i8* %5 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %.elt, %swift.type* %1) #9 %6 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo__AaBQr_QR_tyFQOyQo0_tMD") #8 %7 = bitcast %swift.type* %6 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %0 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e8ortTupleQr_QR_tyFQOyQo0_MD") #8 %12 = bitcast %swift.type* %11 to i8*** %13 = getelementptr inbounds i8**, i8*** %12, i64 -1 %.valueWitnesses2 = load i8**, i8*** %13, align 8, !invariant.load !19, !dereferenceable !20 %14 = getelementptr inbounds i8*, i8** %.valueWitnesses2, i32 1 %15 = load i8*, i8** %14, align 8, !invariant.load !19 %destroy3 = bitcast i8* %15 to void (%swift.opaque*, %swift.type*)* call void %destroy3(%swift.opaque* noalias %.elt1, %swift.type* %11) #9 ret <{}>* %0 } 140
  141. δΣωϦοΫܕͰsomeͷݸ਺Λม͑ͨ৔߹ public struct C<A, B, C> { var a: A

    var b: B var c: C public func getA() -> A { a } public func getB() -> B { b } public func getC() -> C { c } } public func ortGeneric1() -> C<Int, Int, some P> { C<Int, Int, S>(a: 0, b: 1, c: S()) } public func ortGeneric2() -> C<some P, (some P, some P), some P> { C<S, (S, S), S>(a: S(), b: (S(), S()), c: S()) } func main1() { ortGeneric1().getC() } func main2() { ortGeneric2().getC() } 141
  142. શମͷܕ ; $s1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_GMD ---> ; demangling cache variable for type

    metadata for ; e.C<Swift.Int, Swift.Int, <<opaque return type of e.ortGeneric1() -> e.C<Swift.Int, Swift.Int, some>>>.0> define hidden swiftcc void @"$s1f5main1yyF"() #0 { entry: %0 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_GMD") #7 %1 = bitcast %swift.type* %0 to i8*** %2 = getelementptr inbounds i8**, i8*** %1, i64 -1 %.valueWitnesses = load i8**, i8*** %2, align 8, !invariant.load !24, !dereferenceable !25 %3 = bitcast i8** %.valueWitnesses to %swift.vwtable* %4 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %3, i32 0, i32 8 %size = load i64, i64* %4, align 8, !invariant.load !24 %5 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %5) %6 = bitcast i8* %5 to %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %7 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e11ortGeneric1AA1CVyS2iQrGyFQOyQo_MD") #7 %8 = bitcast %swift.type* %7 to i8*** %9 = getelementptr inbounds i8**, i8*** %8, i64 -1 %.valueWitnesses1 = load i8**, i8*** %9, align 8, !invariant.load !24, !dereferenceable !25 %10 = bitcast i8** %.valueWitnesses1 to %swift.vwtable* %11 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %10, i32 0, i32 8 %size2 = load i64, i64* %11, align 8, !invariant.load !24 %12 = alloca i8, i64 %size2, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %12) %13 = bitcast i8* %12 to %swift.opaque* %14 = bitcast %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %6 to %swift.opaque* call swiftcc void @"$s1e11ortGeneric1AA1CVyS2iQrGyF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %14) %15 = bitcast %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %6 to %T1e1CV* call swiftcc void @"$s1e1CV4getCq0_yF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %13, %swift.type* %0, %T1e1CV* noalias nocapture swiftself %15) %16 = call %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* @"$s1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_GWOh"(%T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %6) %17 = getelementptr inbounds i8*, i8** %.valueWitnesses1, i32 1 %18 = load i8*, i8** %17, align 8, !invariant.load !24 %destroy = bitcast i8* %18 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %13, %swift.type* %7) #8 %19 = bitcast %swift.opaque* %13 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %19) %20 = bitcast %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 142
  143. opaque result typeͷ0൪ ; $s1e11ortGeneric1AA1CVyS2iQrGyFQOyQo_MD ---> ; demangling cache variable

    for type metadata for << ; opaque return type of e.ortGeneric1() -> e.C<Swift.Int, Swift.Int, some> ; >>.0 define hidden swiftcc void @"$s1f5main1yyF"() #0 { entry: %0 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_GMD") #7 %1 = bitcast %swift.type* %0 to i8*** %2 = getelementptr inbounds i8**, i8*** %1, i64 -1 %.valueWitnesses = load i8**, i8*** %2, align 8, !invariant.load !24, !dereferenceable !25 %3 = bitcast i8** %.valueWitnesses to %swift.vwtable* %4 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %3, i32 0, i32 8 %size = load i64, i64* %4, align 8, !invariant.load !24 %5 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %5) %6 = bitcast i8* %5 to %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %7 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e11ortGeneric1AA1CVyS2iQrGyFQOyQo_MD") #7 %8 = bitcast %swift.type* %7 to i8*** %9 = getelementptr inbounds i8**, i8*** %8, i64 -1 %.valueWitnesses1 = load i8**, i8*** %9, align 8, !invariant.load !24, !dereferenceable !25 %10 = bitcast i8** %.valueWitnesses1 to %swift.vwtable* %11 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %10, i32 0, i32 8 %size2 = load i64, i64* %11, align 8, !invariant.load !24 %12 = alloca i8, i64 %size2, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %12) %13 = bitcast i8* %12 to %swift.opaque* %14 = bitcast %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %6 to %swift.opaque* call swiftcc void @"$s1e11ortGeneric1AA1CVyS2iQrGyF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %14) %15 = bitcast %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %6 to %T1e1CV* call swiftcc void @"$s1e1CV4getCq0_yF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %13, %swift.type* %0, %T1e1CV* noalias nocapture swiftself %15) %16 = call %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* @"$s1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_GWOh"(%T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %6) %17 = getelementptr inbounds i8*, i8** %.valueWitnesses1, i32 1 %18 = load i8*, i8** %17, align 8, !invariant.load !24 %destroy = bitcast i8* %18 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %13, %swift.type* %7) #8 %19 = bitcast %swift.opaque* %13 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %19) %20 = bitcast %T1e1CVyS2iAA11ortGeneric1ACyS2iQrGyFQOyQo_G* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 143
  144. opaque return typeͷ3൪ ; $s1e11ortGeneric2AA1CVyQrQR__QR0_tQR1_GyFQOyQo2_MD ---> ; demangling cache variable

    for type metadata for << ; opaque return type of e.ortGeneric2() -> e.C<some, (some, some), some> ; >>.3 define hidden swiftcc void @"$s1f5main2yyF"() #0 { entry: %0 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e1CVyAA11ortGeneric2ACyQrQR__QR0_tQR1_GyFQOyQo_AadEyFQOyQo0__AadEyFQOyQo1_tAadEyFQOyQo2_GMD") #7 %1 = bitcast %swift.type* %0 to i8*** %2 = getelementptr inbounds i8**, i8*** %1, i64 -1 %.valueWitnesses = load i8**, i8*** %2, align 8, !invariant.load !24, !dereferenceable !25 %3 = bitcast i8** %.valueWitnesses to %swift.vwtable* %4 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %3, i32 0, i32 8 %size = load i64, i64* %4, align 8, !invariant.load !24 %5 = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %5) %6 = bitcast i8* %5 to %T1e1CVyAA11ortGeneric2ACyQrQR__QR0_tQR1_GyFQOyQo_AadEyFQOyQo0__AadEyFQOyQo1_tAadEyFQOyQo2_G* %7 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName({ i32, i32 }* @"$s1e11ortGeneric2AA1CVyQrQR__QR0_tQR1_GyFQOyQo2_MD") #7 %8 = bitcast %swift.type* %7 to i8*** %9 = getelementptr inbounds i8**, i8*** %8, i64 -1 %.valueWitnesses1 = load i8**, i8*** %9, align 8, !invariant.load !24, !dereferenceable !25 %10 = bitcast i8** %.valueWitnesses1 to %swift.vwtable* %11 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %10, i32 0, i32 8 %size2 = load i64, i64* %11, align 8, !invariant.load !24 %12 = alloca i8, i64 %size2, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %12) %13 = bitcast i8* %12 to %swift.opaque* %14 = bitcast %T1e1CVyAA11ortGeneric2ACyQrQR__QR0_tQR1_GyFQOyQo_AadEyFQOyQo0__AadEyFQOyQo1_tAadEyFQOyQo2_G* %6 to %swift.opaque* call swiftcc void @"$s1e11ortGeneric2AA1CVyQrQR__QR0_tQR1_GyF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %14) %15 = bitcast %T1e1CVyAA11ortGeneric2ACyQrQR__QR0_tQR1_GyFQOyQo_AadEyFQOyQo0__AadEyFQOyQo1_tAadEyFQOyQo2_G* %6 to %T1e1CV* call swiftcc void @"$s1e1CV4getCq0_yF"(%swift.opaque* noalias nocapture sret(%swift.opaque) %13, %swift.type* %0, %T1e1CV* noalias nocapture swiftself %15) %16 = call %T1e1CVyAA11ortGeneric2ACyQrQR__QR0_tQR1_GyFQOyQo_AadEyFQOyQo0__AadEyFQOyQo1_tAadEyFQOyQo2_G* @"$s1e1CVyAA11ortGeneric2ACyQrQR__QR0_tQR1_GyFQOyQo_AadEyFQOyQo0__AadEyFQOyQo1_tAadEyFQOyQo2_GWOh"( %T1e1CVyAA11ortGeneric2ACyQrQR__QR0_tQR1_GyFQOyQo_AadEyFQOyQo0__AadEyFQOyQo1_tAadEyFQOyQo2_G* %6 ) %17 = getelementptr inbounds i8*, i8** %.valueWitnesses1, i32 1 %18 = load i8*, i8** %17, align 8, !invariant.load !24 %destroy = bitcast i8* %18 to void (%swift.opaque*, %swift.type*)* call void %destroy(%swift.opaque* noalias %13, %swift.type* %7) #8 %19 = bitcast %swift.opaque* %13 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %19) %20 = bitcast %T1e1CVyAA11ortGeneric2ACyQrQR__QR0_tQR1_GyFQOyQo_AadEyFQOyQo0__AadEyFQOyQo1_tAadEyFQOyQo2_G* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %20) ret void } 144
  145. ൪߸ͷҙຯ public func ortGeneric1() -> C<Int, Int, some P> {

    ... } public func ortGeneric2() -> C<some P, (some P, some P), some P> { ... } // ؾ࣋ͪ public func ortGeneric1() -> <T0: P> C<Int, Int, T0> { ... } // C.C͸T0 public func ortGeneric2() -> <T0: P, T1: P, T2: P, T3: P> C<T0, (T1, T2), T3> { ... } // C.C͸T3 Reverse GenericsͰݟͨͱ͖ͷύϥϝʔλܕͷΠϯσοΫεʹରԠ͠ ͍ͯΔ? 145
  146. S-ORT ·ͱΊ • ฦΓ஋ͰsomeΛ࢖͑Δܗ͕૿͑ͨ • ϥϯλΠϜؔ਺ͰsomeΛؚΉฦΓ஋ࣗମͷܕΛऔಘͰ͖Δ • ෳ਺ͷsomeΛؚΉ৔߹ɺͦΕͧΕͷsomeʹ൪߸͕෇͍͍ͯ ͯɺݸผͷܕͷऔಘ΋Ͱ͖Δ 146

  147. Named Opaque Types Reverse Generics 147

  148. ࣮͸΋͏࣮૷͕͋ͬͯࢼͤΔɻ $ swiftc \ -Xfrontend -enable-experimental-named-opaque-types \ -emit-module i.swift 148

  149. public protocol P {} struct S: P {} public func

    makeTuple() -> <T: P, U: P> (T, T, U) { (S(), S(), S()) } func main() { let tuple = makeTuple() } ͜͏͢Ε͹ɺReverse Parameter͸2ͭɺopaque type͸3ͭͳͷ Ͱɺ൪߸෇͚ͷنଇ͕ௐ΂ΒΕΔɻ 149
  150. define hidden swiftcc void @"$s1j4mainyyF"() #0 { entry: %tuple.debug =

    alloca i8*, align 8 %0 = bitcast i8** %tuple.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1i9makeTupleQr_QrQR_tyFQOyQo__AcaBQr_QrQR_tyFQOyQo0_tMD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %tuple = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %tuple) %6 = bitcast i8* %tuple to <{}>* store i8* %tuple, i8** %tuple.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = bitcast %swift.type* %1 to %swift.tuple_type* %12 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %11, i64 0, i32 3, i64 2, i32 1 %.2.offset = load i32, i32* %12, align 8 %13 = bitcast <{}>* %6 to i8* %14 = getelementptr inbounds i8, i8* %13, i32 %.2.offset %.elt2 = bitcast i8* %14 to %swift.opaque* call swiftcc void @"$s1i9makeTupleQr_QrQR_tyF"( %swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1, %swift.opaque* noalias nocapture %.elt2) %15 = call <{}>* @"$s1i9makeTupleQr_QrQR_tyFQOyQo__AcaBQr_QrQR_tyFQOyQo0_tWOh"(<{}>* %6) %16 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %16) ret void } 150
  151. γάωνϟ͸ some ͕3ͭɻ ; $s1i9makeTupleQr_QrQR_tyF ---> i.makeTuple() -> (some, some,

    some) define hidden swiftcc void @"$s1j4mainyyF"() #0 { entry: %tuple.debug = alloca i8*, align 8 %0 = bitcast i8** %tuple.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1i9makeTupleQr_QrQR_tyFQOyQo__AcaBQr_QrQR_tyFQOyQo0_tMD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %tuple = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %tuple) %6 = bitcast i8* %tuple to <{}>* store i8* %tuple, i8** %tuple.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = bitcast %swift.type* %1 to %swift.tuple_type* %12 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %11, i64 0, i32 3, i64 2, i32 1 %.2.offset = load i32, i32* %12, align 8 %13 = bitcast <{}>* %6 to i8* %14 = getelementptr inbounds i8, i8* %13, i32 %.2.offset %.elt2 = bitcast i8* %14 to %swift.opaque* call swiftcc void @"$s1i9makeTupleQr_QrQR_tyF"( %swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1, %swift.opaque* noalias nocapture %.elt2) %15 = call <{}>* @"$s1i9makeTupleQr_QrQR_tyFQOyQo__AcaBQr_QrQR_tyFQOyQo0_tWOh"(<{}>* %6) %16 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %16) ret void } 151
  152. ฦΓ஋ͷܕ৘ใΛऔಘ͢ΔՕॴ define hidden swiftcc void @"$s1j4mainyyF"() #0 { entry: %tuple.debug

    = alloca i8*, align 8 %0 = bitcast i8** %tuple.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 8, i1 false) %1 = call %swift.type* @__swift_instantiateConcreteTypeFromMangledName( { i32, i32 }* @"$s1i9makeTupleQr_QrQR_tyFQOyQo__AcaBQr_QrQR_tyFQOyQo0_tMD") #8 %2 = bitcast %swift.type* %1 to i8*** %3 = getelementptr inbounds i8**, i8*** %2, i64 -1 %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !19, !dereferenceable !20 %4 = bitcast i8** %.valueWitnesses to %swift.vwtable* %5 = getelementptr inbounds %swift.vwtable, %swift.vwtable* %4, i32 0, i32 8 %size = load i64, i64* %5, align 8, !invariant.load !19 %tuple = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %tuple) %6 = bitcast i8* %tuple to <{}>* store i8* %tuple, i8** %tuple.debug, align 8 %.elt = bitcast <{}>* %6 to %swift.opaque* %7 = bitcast %swift.type* %1 to %swift.tuple_type* %8 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %7, i64 0, i32 3, i64 1, i32 1 %.1.offset = load i32, i32* %8, align 8 %9 = bitcast <{}>* %6 to i8* %10 = getelementptr inbounds i8, i8* %9, i32 %.1.offset %.elt1 = bitcast i8* %10 to %swift.opaque* %11 = bitcast %swift.type* %1 to %swift.tuple_type* %12 = getelementptr inbounds %swift.tuple_type, %swift.tuple_type* %11, i64 0, i32 3, i64 2, i32 1 %.2.offset = load i32, i32* %12, align 8 %13 = bitcast <{}>* %6 to i8* %14 = getelementptr inbounds i8, i8* %13, i32 %.2.offset %.elt2 = bitcast i8* %14 to %swift.opaque* call swiftcc void @"$s1i9makeTupleQr_QrQR_tyF"( %swift.opaque* noalias nocapture %.elt, %swift.opaque* noalias nocapture %.elt1, %swift.opaque* noalias nocapture %.elt2) %15 = call <{}>* @"$s1i9makeTupleQr_QrQR_tyFQOyQo__AcaBQr_QrQR_tyFQOyQo0_tWOh"(<{}>* %6) %16 = bitcast <{}>* %6 to i8* call void @llvm.lifetime.end.p0i8(i64 -1, i8* %16) ret void } 152
  153. $s1i9makeTupleQr_QrQR_tyFQOyQo__AcaBQr_QrQR_tyFQOyQo0_tMD ---> demangling cache variable for type metadata for (

    <<opaque return type of i.makeTuple() -> (some, some, some)>>.0, <<opaque return type of i.makeTuple() -> (some, some, some)>>.0, <<opaque return type of i.makeTuple() -> (some, some, some)>>.1 ) λϓϧͷܕ͸ (0, 0, 1) ͳͷͰɺopaque return typeͷ൪߸ ͸ɺReverse Generic ParameterͷฒͼʹରԠ͍ͯ͠ΔͱΘ͔ Δɻ 153
  154. SE-0341: Opaque Parameter Declarations func f(p: some P) { ...

    } // ౳Ձ func f<T: P>(p: T) { ... } someΛҾ਺Ͱ࢖͑ΔɻͦΕͧΕͷsome͕ݸผͷܕύϥϝʔλ ͱͳΔɻ 154
  155. Structural func foo(_ a: (some P, some P)) {} ΋ͪΖΜλϓϧͳͲͷδΣωϦοΫύϥϝʔλͷதʹ࢖͏͜ͱ

    ΋Ͱ͖Δɻ 155
  156. Ҿ਺ͷؔ਺ͷҾ਺෦෼͸ͩΊ func foo(_ f: (some P) -> Void) {} fooͷதͰfʹ౉͢

    some P Λ࡞Δํ๏͕ͳ͍ 156
  157. ίʔυੜ੒΁ͷӨڹ͸ͳ͍ func foo(_ a: (some P, some P)) {} define

    hidden swiftcc void @"$s1g3fooyyx_q_t_tAA1PRzAaCR_r0_lF"( %swift.opaque* noalias nocapture %0, %swift.opaque* noalias nocapture %1, %swift.type* %"<anonymous>", %swift.type* %"<anonymous>1", i8** %"<anonymous>.P", i8** %"<anonymous>.P2" ) { ... } ; $s1g3fooyyx_q_t_tAA1PRzAaCR_r0_lF ---> ; g.foo<A, B where A: g.P, B: g.P>((A, B)) -> () σϚϯάϧ͢Ε͹௨ৗͷδΣωϦΫεʹͳ͍ͬͯΔࣄ͕֬ೝͰ͖Δ 157
  158. SE-0346: Lightweight same-type requirements for primary associated types func readSyntaxHighlightedLines(_

    file: String) -> some Sequence<[Token]> { ... } ϓϩτίϧ໊ͷޙΖʹࡾׅ֯ހͰύϥϝʔλࢦఆͯ͠ɺ associated typeͷ੍໿Λॻ͚Δ 158
  159. એݴଆͰprimaryࢦఆ͢Δ protocol Sequence<Element> { associatedtype Element associatedtype Iterator : IteratorProtocol

    where Element == Iterator.Element ... } ϓϩτίϧ໊ͷޙΖʹࡾׅ֯ހͰύϥϝʔλએݴ͓ͯ͘͠ɻ associated typeͷ໊લΛॻ͘ɻ 159
  160. Generic Protocolͱͷিಥճආ associated type͸protocol conformanceͷࡍʹݻఆ͢Δ಺෦ύϥϝʔλ͕ͩɺ ֎෦ύϥϝʔλ͝ͱʹҟͳΔconformanceͱΈͳ͢Generic Protocolͱ͍͏ΞΠσΞ͕͋Δɻ ࡾׅ֯ހ͸কདྷͦͷΑ͏ͳػೳʹ࢖͍ͦ͏͕ͩͬͨɺࠓճผͷ༻్ʹফඅͯ͠͠·ͬͨɻ ఏҊͰ͸ɺGeneric Protocolʹ͸ؙׅހͷҊ͕ࣔ͞Ε͍ͯΔɻ

    protocol Convertible(from: Self, to: Other) { static func convert(_: Self) -> Other } extension Convertible(from: String, to: Int) { static func convert(_: String) -> Int } extension Convertible(from: String, to: Double) { static func convert(_: String) -> Int } 160
  161. ίʔυੜ੒΁ͷӨڹ͸ͳ͍ protocol P<A> { associatedtype A } struct S<A>: P

    {} func foo(a: some P<Int>) -> some P<Bool> { ... } define hidden swiftcc void @"$s1g3foo1aQrx_tAA1PRzSi1ARtzlF"( %swift.opaque* noalias nocapture sret(%swift.opaque) %0, %swift.opaque* noalias nocapture %1, %swift.type* %"<anonymous>", i8** %"<anonymous>.P" ) #0 { ... } ; $s1g3foo1aQrx_tAA1PRzSi1ARtzlF ---> ; g.foo<A where A: g.P, A.A == Swift.Int>(a: A) -> some 161
  162. ٙ໰: ORTͱγάωνϟ // $s1g3fooQryF ---> g.foo() -> some func foo()

    -> some P<Int> { ... } // $s1g3fooQryF ---> g.foo() -> some func foo() -> some Q { ... } // $s1g3fooQr_QR_tyF ---> g.foo() -> (some, some) func foo() -> (some Q, some Q) { ... } ORTͷδΣωϦοΫ੍໿෦෼͸ͦΕࣗମͷ੍໿(P)΍associated type(Int)ΛؚΊશ ͘γάωνϟʹ৐Βͳ͍ͷͰɺ ੍໿Ͱ͸ΦʔόʔϩʔυͰ͖ͳ͍͕ɺܗͰ͸ΦʔόʔϩʔυͰ͖Δɻ 162
  163. SE-0352: Implicitly Opened Existentials protocol P { associatedtype A }

    func useSomeP(_ p: some P) {} func useAnyP(_ p: any P) { useSomeP(p) } existentialΛؔ਺ݺͼग़͠ͷͱ͖ʹopenͰ͖Δɻͭ·ΓɺanyΛsomeʹม׵Ͱ͖Δɻ 163
  164. ϋοΫ͕ෆཁʹͳͬͨ extension P { func callUseSomeP() { useSomeP(self) } }

    func useAnyP(_ p: any P) { p.callUseSomeP(p) } ٕज़తʹ͸existentialʹΑΔopenͰͰ͖͍ͯͨࣄΛɺ Ͳ͜Ͱ΋खؒͳ͠Ͱ࢖͑ΔΑ͏ʹͳͬͨͱΈͳͤΔɻ 164
  165. inoutʹ΋౉ͤΔ func useSomeP(_ p: inout some P) {} func useAnyP(_

    p: any P) { var p = p useSomeP(&p) } 165
  166. ౉ͤͳ͍ྫ 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 cannotOpenDemo( array: [any P], p1: any P, p2: any P, xp: X<any P>, pOpt: (any P)? ) { cannotOpen1(array) // ཁૉͷܕ͕ҟͳΔ͔΋͠Εͳ͍͠ɺۭ͔΋͠Εͳ͍ cannotOpen2(p1, p2) // p1ͱp2ͷܕ͕ҟͳΔ͔΋͠Εͳ͍ cannotOpen3(p1, p2) // p1ͱp2ͷܕ͕ҟͳΔ͔΋͠Εͳ͍ cannotOpen4(xp) // த਎ΛऔΓग़͢ํ๏͕ͳ͍ cannotOpen5(p1, p2.getA()) // p1ͱp2ͷܕ͕ҟͳΔ͔΋͠Εͳ͍ cannotOpen5(p1, p1.getA()) // p1ͱp1.getA()ͷܕͷؔ࿈͸௥੻͞Εͳ͍ cannotOpen6(pOpt) // த਎͕ͳ͍͔΋͠Εͳ͍ } open͢Δʹ͸ any P ͷத਎ͷਅͷ஋͕ඞཁɻ 166
  167. Existential Metatype Container func useSomePType<T: P>(_ t: T.Type) {} func

    useAnyPType(_ t: any P.Type) { useSomePType(t) } ϝλλΠϓͷexistential΋openͰ͖Δ 167
  168. open݁Ռͷerase protocol P { associatedtype A: AP func getA() ->

    A } protocol AP {} func decompose<T: P>(_ p: T) -> (T, T.A) { (p, p.getA()) } func useAnyP(_ p: any P) { let (p, a) = decompose(p) } 168
  169. openͨؔ͠਺ͷฦΓ஋͸upper boundͷexistentialʹerase͞Ε Δɻ func useAnyP(_ p: any P) { let

    (p, a): (any P, any AP) = decompose(p) } 169
  170. SE-0309ͷexistentialͷ੍ݶഉআͰಋೖ͞Εͨɺcovariantͳ associated value͕erase͞ΕΔͷͱಉ͡࢓૊Έɻ func useAnyP(_ p: any P) { let

    a: any AP = p.getA() } 170
  171. contravariantͩͱopenͰ͖ͳ͍ func makeFunc<T: P>(_ p: T) -> (T) -> ()

    { return { (_) in } } func useAnyP(_ p: any P) { // error: type 'any P' cannot conform to 'P' makeFunc(p) } 171
  172. invariant΋openͰ͖ͳ͍ struct X<T> { var t: T } func wrapX<T:

    P>(_ p: T) -> X<T> { ... } func useAnyP(_ p: any P) { // error: type 'any P' cannot conform to 'P' wrapX(p) } Ϣʔβఆٛgenerics͸invariantͳͷͰcontravariant 172
  173. Ҿ਺ͷҾ਺͸covariant func acceptValueAndFunction<T: P>(_ value: T, body: (T) -> Void)

    { ... } func testContravariantErasure(p: any P) { acceptValueAndFunction(p) { (innerValue: any P) in ... } } 173
  174. erase͠ͳ͍Ͱͦͷ··bind͢Δ func takeP<U: P>(_: U) -> Void { ... }

    func implicitOpeningArguments(p: any P) { acceptValueAndFunction(p, body: takeP) } takePͷU͕௚઀pͷਅͷܕʹͳΔɻ erase͔ͯ͠Β࠶౓open͍ͯ͠Δͱ΋ݟ၏ͤΔɻ 174
  175. erase࣌ͷ੍໿૕ࣦ໰୊ protocol P { associatedtype A } protocol Q {

    associatedtype B: P where B.A == Int } func getBFromQ<T: Q>(_ q: T) -> T.B { ... } func eraseQAssoc(q: any Q) { let b = getBFromQ(q) } getBFromQͷฦΓ஋ͷܕ͸ <U: P> where P.A == Int ͕ͩɺ b ʹerase͢Δͱ͖ʹ any P ʹͳΓɺA == Int ͷ੍໿͕૕ࣦ͢Δɻ 175
  176. ͜ͷ໰୊͸existential੍͕໿Λ࣋ͯͳ͍ࣄʹىҼ͢Δɻ কདྷతʹղܾͨ͠৔߹ɺb ͷܕ͸ΑΓਖ਼֬ʹͳΔ͕ɺιʔεޓ׵ੑ͕յΕΔɻ // b: any P ͳΒͬͪ͜ func f<T:

    P>(_: T) -> Int { 17 } // b: any P<Int> ͳΒͬͪ͜ func f<T: P>(_: T) -> Double where T.A == Int { 3.14159 } func eraseQAssoc(q: any Q) { let b = getBFromQ(q) // Ͳͬͪʁ f(b) } 176
  177. ͦ͜Ͱɺ੍໿͕૕ࣦ͢Δeraseʹ͸໌ࣔతͳasΛڧ੍͢Δɻ func eraseQAssoc(q: any Q) { let b = getBFromQ(q)

    as any P } 177
  178. SE-0309΋ಉ͡໰୊͕͋ͬͨͷͰ໌ࣔతͳasΛڧ੍͢Δɻ extension Q { func getBFromQ() -> B { ...

    } } func eraseQAssocWithSE0309(q: any Q) { let b = q.getBFromQ() as any P } 178
  179. Ҿ਺ͷධՁॱͱopenͷલޙॱ໰୊ extension Int: P { } func getP() -> any

    P { print("getP()") return 17 } func acceptFunctionStringAndValue<T: P>(body: (T) -> Void, string: String, value: T) { ... } func hello() -> String { print("hello()") return "hello" } func implicitOpeningArgumentsBackwards() { acceptFunctionStringAndValue(body: takeP, string: hello(), value: getP()) } 179
  180. acceptFunctionStringAndValue(body: takeP, string: hello(), value: getP()) takePΛධՁ͢ΔͨΊʹ͸ɺ<T> ʹਅͷܕ͕ଋറ͞Εͳ͚Ε͹ͳ Βͳ͍ɻ ͔͠͠ɺ

    <T> ͸ getP ͷฦΓ஋Λopen͠ͳ͚Ε͹ܾఆͰ͖ͳ͍ɻ ͦͷ݁ՌɺgetP() → takeP → hello() ͷॱʹධՁ͞Εɺ෭࡞༻ ͱͯ͠ҎԼ͕ग़ྗ͞ΕΔɻ getP() hello() ͜Ε͸Swiftͷࠨ͔ΒӈʹҾ਺ΛධՁ͢Δنଇͱໃ६͢Δɻ 180
  181. ͦ͜Ͱɺ͢ͰʹࠨଆͰ࢖ΘΕͨδΣωϦοΫύϥϝʔλΛɺ ͦΕΑΓӈଆͰopen͢Δࣄ͸Ͱ͖ͳ͍ɺͱ͍͏ϧʔϧΛ௥Ճ͢ Δɻ // error: type 'any P' cannot conform

    to 'P' acceptFunctionStringAndValue(body: takeP, string: hello(), value: getP()) 181
  182. openͷޓ׵ੑ໰୊ func acceptsBox<T>(_ value: T) -> Any { [value] }

    func passBox(p: any P) { let result = acceptsBox(p) // ͜Ε·Ͱ͸ result: [any P] // ͜Ε͔Β͸ result: [open(any P)] } 182
  183. ࣗݾ४ڌ͢Δexistential(Errorͱ@objc)΋໰୊ʹͳΔɻ func takeError<E: Error>(_ error: E) { ... } func

    passError(error: any Error) { takeError(error) // ͜Ε·Ͱ͸ E = any Error // ͜Ε͔Β͸ E = open(any Error) } 183
  184. কདྷɺexistentialΛࣗݾ४ڌͤ͞Δจ๏͕௥Ճ͞ΕΔ৔߹ɺ͜Ε ʹ͍ͭͯ͸ޓ׵ੑͷ໰୊͸ੜ͡ͳ͍ͷͰopen͢Δɻ extension any P: P {} 184

  185. طଘͷ໰୊ʹ͍ͭͯ͸ޓ׵ੑҡ࣋ͷͨΊɺSwift5Ͱ͸open͠ͳ ͍ࣄʹ͢Δɻ Swift6Ͱ͸ޓ׵ੑഁյͰ͖ΔͷͰɺopenͰ͖Δͱ͖͸open͢Δ Α͏ʹมߋ͢Δɻ 185

  186. open཈੍ه๏ ໌ࣔతͳasʹΑͬͯɺopenΛ཈੍Ͱ͖Δɻ // (1) func f<T>(_: T) { } //

    (2) func f<T: P>(_: T) { } func test(p: any P) { // pΛopenͯ͠(2)ΛݺͿ f(p) // pͷopenΛ཈੍͢ΔͨΊ(1)ΛݺͿ f(p as any P) } 186
  187. open཈੍ͷແޮԽه๏ ؙׅހΛ෇͚Δͱopenͷ཈੍ΛແޮԽͰ͖Δ func test(p: any P) { // openͷ཈੍ΛແޮԽ͢ΔͨΊɺopenͯ͠(1)ΛݺͿ f((p

    as any P)) } 187
  188. ੍໿૕ࣦ࣌ͷasͷ໌ࣔͱͷׯব protocol P { associatedtype A } protocol Q {

    associatedtype B: P where B.A == Int } func getP<T: P>(_ p: T) func getBFromQ<T: Q>(_ q: T) -> T.B { ... } func eraseQAssoc(q: any Q) { // A == Int ͕૕ࣦ͢ΔͷͰ as any P ͕ඞཁ getP(getBFromQ(q)) // ੍໿૕ࣦ͕ڐ༰͞Ε͕ͨɺopen΋཈੍͢ΔͨΊgetP͕ݺͼग़ͤͳ͍ getP(getBFromQ(q) as any P) // ੍໿૕ࣦΛڐ༰͠ɺopenͷ཈੍ΛແޮԽͨ͠ͷͰɺgetP͕ݺͼग़ͤΔ getP((getBFromQ(q) as any P)) } 188
  189. ҉໧ͷopen·ͱΊ • ؔ਺ݺͼग़͠ͰopenͰ͖Δ • openͨ͠ܕ͕໭ͬͯ͘Δ৔߹erase͞ΕΔ • ཈੍ه๏΋͋Δ 189

  190. SE-0353: Constrained Existential Types primary associated typeΛࢦఆͨ͠existential͕࢖͑Δ any Collection<Int> 190

  191. upper bound΁ͷeraseͰͷ੍໿ͷ૕ࣦΛ๷͙ protocol P<A> { associatedtype A } protocol Q

    { associatedtype B: P where B.A == Int } 191
  192. ExistentialͷϝϯόʹΞΫηε͢Δ࣌ extension Q { func getB() -> B } func

    useQ(_ q: any Q) { let b: any P<Int> = q.getB() } 192
  193. Open͢Δ࣌ func getB<T: Q>(_ q: T) -> T.B { ...

    } func useQ(_ q: any Q) { let b: any P<Int> = getB(q) } 193
  194. Constrained Existential Typeͷ࣮ ૷ 194

  195. protocol P<A> { associatedtype A func getA() -> A }

    func useIntP(_ p: any P<Int>) { let a: Int = p.getA() } 195
  196. define hidden swiftcc void @"$s1h7useIntPyyAA1P_pySiXPF"(%T1h1P_pySiXP* noalias nocapture dereferenceable(40) %0) #0

    { entry: %p.debug = alloca %T1h1P_pySiXP*, align 8 %1 = bitcast %T1h1P_pySiXP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) %2 = alloca %TSi, align 8 %a.debug = alloca i64, align 8 %3 = bitcast i64* %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %3, i8 0, i64 8, i1 false) store %T1h1P_pySiXP* %0, %T1h1P_pySiXP** %p.debug, align 8 %4 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 1 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 2 %7 = load i8**, i8*** %6, align 8 %8 = bitcast %T1h1P_pySiXP* %0 to %__opaque_existential_type_1* %9 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %8, %swift.type* %5) #5 %10 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %10) %11 = getelementptr inbounds i8*, i8** %7, i32 2 %12 = load i8*, i8** %11, align 8, !invariant.load !21 %13 = bitcast i8* %12 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %14 = bitcast %TSi* %2 to %swift.opaque* call swiftcc void %13(%swift.opaque* noalias nocapture sret(%swift.opaque) %14, %swift.opaque* noalias nocapture swiftself %9, %swift.type* %5, i8** %7) %._value = getelementptr inbounds %TSi, %TSi* %2, i32 0, i32 0 %15 = load i64, i64* %._value, align 8 store i64 %15, i64* %a.debug, align 8 %16 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) ret void } 196
  197. ; $s1h7useIntPyyAA1P_pySiXPF ---> h.useIntP(h.P<Swift.Int>) -> () %T1h1P_pySiXP = type {

    [24 x i8], %swift.type*, i8** } define hidden swiftcc void @"$s1h7useIntPyyAA1P_pySiXPF"(%T1h1P_pySiXP* noalias nocapture dereferenceable(40) %0) #0 { ... } 197
  198. IntͷϝϞϦ֬อͱopaqueܕ΁ͷม׵ define hidden swiftcc void @"$s1h7useIntPyyAA1P_pySiXPF"(%T1h1P_pySiXP* noalias nocapture dereferenceable(40) %0)

    #0 { entry: %p.debug = alloca %T1h1P_pySiXP*, align 8 %1 = bitcast %T1h1P_pySiXP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) %2 = alloca %TSi, align 8 %a.debug = alloca i64, align 8 %3 = bitcast i64* %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %3, i8 0, i64 8, i1 false) store %T1h1P_pySiXP* %0, %T1h1P_pySiXP** %p.debug, align 8 %4 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 1 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 2 %7 = load i8**, i8*** %6, align 8 %8 = bitcast %T1h1P_pySiXP* %0 to %__opaque_existential_type_1* %9 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %8, %swift.type* %5) #5 %10 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %10) %11 = getelementptr inbounds i8*, i8** %7, i32 2 %12 = load i8*, i8** %11, align 8, !invariant.load !21 %13 = bitcast i8* %12 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %14 = bitcast %TSi* %2 to %swift.opaque* call swiftcc void %13(%swift.opaque* noalias nocapture sret(%swift.opaque) %14, %swift.opaque* noalias nocapture swiftself %9, %swift.type* %5, i8** %7) %._value = getelementptr inbounds %TSi, %TSi* %2, i32 0, i32 0 %15 = load i64, i64* %._value, align 8 store i64 %15, i64* %a.debug, align 8 %16 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) ret void } 198
  199. openͯ͠ܕɺPWTɺ஋ͷऔΓग़͠ define hidden swiftcc void @"$s1h7useIntPyyAA1P_pySiXPF"(%T1h1P_pySiXP* noalias nocapture dereferenceable(40) %0)

    #0 { entry: %p.debug = alloca %T1h1P_pySiXP*, align 8 %1 = bitcast %T1h1P_pySiXP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) %2 = alloca %TSi, align 8 %a.debug = alloca i64, align 8 %3 = bitcast i64* %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %3, i8 0, i64 8, i1 false) store %T1h1P_pySiXP* %0, %T1h1P_pySiXP** %p.debug, align 8 %4 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 1 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 2 %7 = load i8**, i8*** %6, align 8 %8 = bitcast %T1h1P_pySiXP* %0 to %__opaque_existential_type_1* %9 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %8, %swift.type* %5) #5 %10 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %10) %11 = getelementptr inbounds i8*, i8** %7, i32 2 %12 = load i8*, i8** %11, align 8, !invariant.load !21 %13 = bitcast i8* %12 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %14 = bitcast %TSi* %2 to %swift.opaque* call swiftcc void %13(%swift.opaque* noalias nocapture sret(%swift.opaque) %14, %swift.opaque* noalias nocapture swiftself %9, %swift.type* %5, i8** %7) %._value = getelementptr inbounds %TSi, %TSi* %2, i32 0, i32 0 %15 = load i64, i64* %._value, align 8 store i64 %15, i64* %a.debug, align 8 %16 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) ret void } 199
  200. PWT͔Βؔ਺ͷऔΓग़͠ define hidden swiftcc void @"$s1h7useIntPyyAA1P_pySiXPF"(%T1h1P_pySiXP* noalias nocapture dereferenceable(40) %0)

    #0 { entry: %p.debug = alloca %T1h1P_pySiXP*, align 8 %1 = bitcast %T1h1P_pySiXP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) %2 = alloca %TSi, align 8 %a.debug = alloca i64, align 8 %3 = bitcast i64* %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %3, i8 0, i64 8, i1 false) store %T1h1P_pySiXP* %0, %T1h1P_pySiXP** %p.debug, align 8 %4 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 1 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 2 %7 = load i8**, i8*** %6, align 8 %8 = bitcast %T1h1P_pySiXP* %0 to %__opaque_existential_type_1* %9 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %8, %swift.type* %5) #5 %10 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %10) %11 = getelementptr inbounds i8*, i8** %7, i32 2 %12 = load i8*, i8** %11, align 8, !invariant.load !21 %13 = bitcast i8* %12 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %14 = bitcast %TSi* %2 to %swift.opaque* call swiftcc void %13(%swift.opaque* noalias nocapture sret(%swift.opaque) %14, %swift.opaque* noalias nocapture swiftself %9, %swift.type* %5, i8** %7) %._value = getelementptr inbounds %TSi, %TSi* %2, i32 0, i32 0 %15 = load i64, i64* %._value, align 8 store i64 %15, i64* %a.debug, align 8 %16 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) ret void } 200
  201. ؔ਺ݺͼग़͠ define hidden swiftcc void @"$s1h7useIntPyyAA1P_pySiXPF"(%T1h1P_pySiXP* noalias nocapture dereferenceable(40) %0)

    #0 { entry: %p.debug = alloca %T1h1P_pySiXP*, align 8 %1 = bitcast %T1h1P_pySiXP** %p.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 0, i64 8, i1 false) %2 = alloca %TSi, align 8 %a.debug = alloca i64, align 8 %3 = bitcast i64* %a.debug to i8* call void @llvm.memset.p0i8.i64(i8* align 8 %3, i8 0, i64 8, i1 false) store %T1h1P_pySiXP* %0, %T1h1P_pySiXP** %p.debug, align 8 %4 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 1 %5 = load %swift.type*, %swift.type** %4, align 8 %6 = getelementptr inbounds %T1h1P_pySiXP, %T1h1P_pySiXP* %0, i32 0, i32 2 %7 = load i8**, i8*** %6, align 8 %8 = bitcast %T1h1P_pySiXP* %0 to %__opaque_existential_type_1* %9 = call %swift.opaque* @__swift_project_boxed_opaque_existential_1(%__opaque_existential_type_1* %8, %swift.type* %5) #5 %10 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.start.p0i8(i64 8, i8* %10) %11 = getelementptr inbounds i8*, i8** %7, i32 2 %12 = load i8*, i8** %11, align 8, !invariant.load !21 %13 = bitcast i8* %12 to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)* %14 = bitcast %TSi* %2 to %swift.opaque* call swiftcc void %13(%swift.opaque* noalias nocapture sret(%swift.opaque) %14, %swift.opaque* noalias nocapture swiftself %9, %swift.type* %5, i8** %7) %._value = getelementptr inbounds %TSi, %TSi* %2, i32 0, i32 0 %15 = load i64, i64* %._value, align 8 store i64 %15, i64* %a.debug, align 8 %16 = bitcast %TSi* %2 to i8* call void @llvm.lifetime.end.p0i8(i64 8, i8* %16) ret void } 201
  202. Constrained Existential Typeͷ·ͱΊ • ࡾׅ֯ހͰͷܕύϥϝʔλࢦఆΛexistentialʹ΋ద༻ͨ͠ • upper bound͕ΑΓਖ਼֬ʹͳΔ • ར༻ՕॴͷγάωνϟʹӨڹ͢Δ

    • ExistentialͷϨΠΞ΢τʹ͸มԽͳ͠ 202
  203. ৽ػೳ·ͱΊ • someͷ༻๏͕֦େͨ͠ • any͕ಋೖ͞Εɺ༻๏͕֦େͨ͠ • upper boundʹΑΔeraseͷ֓೦͕௥Ճ͞Εͨ • ࣗવͳopen͕Ͱ͖ΔΑ͏ʹͳͬͨ

    • primary associated type͕ಋೖ͞Εͨ 203
  204. ࠓޙͷల๬ • ඇprimaryͳassociated typeͷexistential΁ͷࢦఆ • existentialͷࣗݾ४ڌจ๏ • Reverse GenericsʹΑΔࣗ༝ͳORT 204