88
99protocol P {
1010 func f( ) -> Self
11+ subscript( ) -> Self { get }
12+ var p : Self { get }
1113}
1214
1315protocol CP : class {
1416 func f( ) -> Self
17+ subscript( ) -> Self { get }
18+ var p : Self { get }
1519}
1620
1721class X : P , CP {
@@ -20,6 +24,12 @@ class X : P, CP {
2024 // CHECK-LABEL: sil hidden [ossa] @$s12dynamic_self1XC1f{{[_0-9a-zA-Z]*}}F : $@convention(method) (@guaranteed X) -> @owned
2125 func f( ) -> Self { return self }
2226
27+ // CHECK-LABEL: sil hidden [ossa] @$s12dynamic_self1XCACXDycig : $@convention(method) (@guaranteed X) -> @owned X
28+ subscript( ) -> Self { self }
29+
30+ // CHECK-LABEL: sil hidden [ossa] @$s12dynamic_self1XC1pACXDvg : $@convention(method) (@guaranteed X) -> @owned X
31+ var p : Self { self }
32+
2333 // CHECK-LABEL: sil hidden [ossa] @$s12dynamic_self1XC7factory{{[_0-9a-zA-Z]*}}FZ : $@convention(method) (Int, @thick X.Type) -> @owned X
2434 // CHECK: bb0([[I:%[0-9]+]] : $Int, [[SELF:%[0-9]+]] : $@thick X.Type):
2535 // CHECK: [[DYNAMIC_SELF:%[0-9]+]] = unchecked_trivial_bit_cast [[SELF]] : $@thick X.Type to $@thick @dynamic_self X.Type
@@ -83,17 +93,65 @@ func testExistentialDispatch(p: P) {
8393// CHECK: destroy_addr [[P_RESULT]] : $*P
8494// CHECK: dealloc_stack [[P_RESULT]] : $*P
8595 _ = p. f ( )
96+
97+ // CHECK: [[PCOPY_ADDR:%[0-9]+]] = open_existential_addr immutable_access [[P]] : $*P to $*@opened([[N:".*"]]) P
98+ // CHECK: [[P_RESULT:%[0-9]+]] = alloc_stack $P
99+ // CHECK: [[PCOPY_ADDR_1:%[0-9]+]] = alloc_stack $@opened([[N]]) P
100+ // CHECK: copy_addr [[PCOPY_ADDR]] to [initialization] [[PCOPY_ADDR_1]] : $*@opened([[N]]) P
101+ // CHECK: [[P_P_GETTER:%[0-9]+]] = witness_method $@opened([[N]]) P, #P.p!getter : {{.*}}, [[PCOPY_ADDR]]{{.*}} : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
102+ // CHECK: [[P_RESULT_ADDR2:%[0-9]+]] = init_existential_addr [[P_RESULT]] : $*P, $@opened([[N]]) P
103+ // CHECK: apply [[P_P_GETTER]]<@opened([[N]]) P>([[P_RESULT_ADDR2]], [[PCOPY_ADDR_1]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
104+ // CHECK: destroy_addr [[PCOPY_ADDR_1]] : $*@opened([[N]]) P
105+ // CHECK: destroy_addr [[P_RESULT]] : $*P
106+ // CHECK: dealloc_stack [[PCOPY_ADDR_1]] : $*@opened([[N]]) P
107+ // CHECK: dealloc_stack [[P_RESULT]] : $*P
108+ _ = p. p
109+
110+ // CHECK: [[PCOPY_ADDR:%[0-9]+]] = open_existential_addr immutable_access [[P]] : $*P to $*@opened([[N:".*"]]) P
111+ // CHECK: [[P_RESULT:%[0-9]+]] = alloc_stack $P
112+ // CHECK: [[PCOPY_ADDR_1:%[0-9]+]] = alloc_stack $@opened([[N]]) P
113+ // CHECK: copy_addr [[PCOPY_ADDR]] to [initialization] [[PCOPY_ADDR_1]] : $*@opened([[N]]) P
114+ // CHECK: [[P_SUBSCRIPT_GETTER:%[0-9]+]] = witness_method $@opened([[N]]) P, #P.subscript!getter : {{.*}}, [[PCOPY_ADDR]]{{.*}} : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
115+ // CHECK: [[P_RESULT_ADDR:%[0-9]+]] = init_existential_addr [[P_RESULT]] : $*P, $@opened([[N]]) P
116+ // CHECK: apply [[P_SUBSCRIPT_GETTER]]<@opened([[N]]) P>([[P_RESULT_ADDR]], [[PCOPY_ADDR_1]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
117+ // CHECK: destroy_addr [[PCOPY_ADDR_1]] : $*@opened([[N]]) P
118+ // CHECK: destroy_addr [[P_RESULT]] : $*P
119+ // CHECK: dealloc_stack [[PCOPY_ADDR_1]] : $*@opened([[N]]) P
120+ // CHECK: dealloc_stack [[P_RESULT]] : $*P
121+ _ = p [ ]
86122}
87123
88124// CHECK-LABEL: sil hidden [ossa] @$s12dynamic_self28testExistentialDispatchClass{{[_0-9a-zA-Z]*}}F : $@convention(thin) (@guaranteed CP) -> ()
125+ func testExistentialDispatchClass( cp: CP ) {
89126// CHECK: bb0([[CP:%[0-9]+]] : @guaranteed $CP):
90127// CHECK: [[CP_ADDR:%[0-9]+]] = open_existential_ref [[CP]] : $CP to $@opened([[N:".*"]]) CP
91128// CHECK: [[CP_F:%[0-9]+]] = witness_method $@opened([[N]]) CP, #CP.f : {{.*}}, [[CP_ADDR]]{{.*}} : $@convention(witness_method: CP) <τ_0_0 where τ_0_0 : CP> (@guaranteed τ_0_0) -> @owned τ_0_0
92129// CHECK: [[CP_F_RESULT:%[0-9]+]] = apply [[CP_F]]<@opened([[N]]) CP>([[CP_ADDR]]) : $@convention(witness_method: CP) <τ_0_0 where τ_0_0 : CP> (@guaranteed τ_0_0) -> @owned τ_0_0
93130// CHECK: [[RESULT_EXISTENTIAL:%[0-9]+]] = init_existential_ref [[CP_F_RESULT]] : $@opened([[N]]) CP : $@opened([[N]]) CP, $CP
94131// CHECK: destroy_value [[RESULT_EXISTENTIAL]]
95- func testExistentialDispatchClass( cp: CP ) {
96132 _ = cp. f ( )
133+
134+ // CHECK: [[CP_ADDR:%[0-9]+]] = open_existential_ref [[CP]] : $CP to $@opened([[N:".*"]]) CP
135+ // CHECK: [[CP_ADDR_1:%[0-9]+]] = copy_value [[CP_ADDR]] : $@opened([[N]]) CP
136+ // CHECK: [[CP_BORROWED:%[0-9]+]] = begin_borrow [[CP_ADDR_1]] : $@opened([[N]]) CP
137+ // CHECK: [[CP_P_GETTER:%[0-9]+]] = witness_method $@opened([[N]]) CP, #CP.p!getter : {{.*}}, [[CP_ADDR]]{{.*}} : $@convention(witness_method: CP) <τ_0_0 where τ_0_0 : CP> (@guaranteed τ_0_0) -> @owned τ_0_0
138+ // CHECK: [[APPLY_RESULT:%[0-9]+]] = apply [[CP_P_GETTER]]<@opened([[N]]) CP>([[CP_BORROWED]]) : $@convention(witness_method: CP) <τ_0_0 where τ_0_0 : CP> (@guaranteed τ_0_0) -> @owned τ_0_0
139+ // CHECK: end_borrow [[CP_BORROWED]] : $@opened([[N]]) CP
140+ // CHECK: destroy_value [[CP_ADDR_1]] : $@opened([[N]]) CP
141+ // CHECK: [[RESULT_EXISTENTIAL:%[0-9]+]] = init_existential_ref [[APPLY_RESULT]] : $@opened([[N]]) CP : $@opened([[N]]) CP, $CP
142+ // CHECK: destroy_value [[RESULT_EXISTENTIAL]] : $CP
143+ _ = cp. p
144+
145+ // CHECK: [[CP_ADDR:%[0-9]+]] = open_existential_ref [[CP]] : $CP to $@opened([[N:".*"]]) CP
146+ // CHECK: [[CP_ADDR_1:%[0-9]+]] = copy_value [[CP_ADDR]] : $@opened([[N]]) CP
147+ // CHECK: [[CP_BORROWED:%[0-9]+]] = begin_borrow [[CP_ADDR_1]] : $@opened([[N]]) CP
148+ // CHECK: [[CP_SUBSCRIPT_GETTER:%[0-9]+]] = witness_method $@opened([[N]]) CP, #CP.subscript!getter : {{.*}}, [[CP_ADDR]]{{.*}} : $@convention(witness_method: CP) <τ_0_0 where τ_0_0 : CP> (@guaranteed τ_0_0) -> @owned τ_0_0
149+ // CHECK: [[APPLY_RESULT:%[0-9]+]] = apply [[CP_SUBSCRIPT_GETTER]]<@opened([[N]]) CP>([[CP_BORROWED]]) : $@convention(witness_method: CP) <τ_0_0 where τ_0_0 : CP> (@guaranteed τ_0_0) -> @owned τ_0_0
150+ // CHECK: end_borrow [[CP_BORROWED]] : $@opened([[N]]) CP
151+ // CHECK: destroy_value [[CP_ADDR_1]] : $@opened([[N]]) CP
152+ // CHECK: [[RESULT_EXISTENTIAL:%[0-9]+]] = init_existential_ref [[APPLY_RESULT]] : $@opened([[N]]) CP : $@opened([[N]]) CP, $CP
153+ // CHECK: destroy_value [[RESULT_EXISTENTIAL]] : $CP
154+ _ = cp [ ]
97155}
98156
99157@objc class ObjC {
0 commit comments