|
| 1 | +// RUN: %empty-directory(%t/src) |
| 2 | +// RUN: split-file %s %t/src |
| 3 | + |
| 4 | +/// Build the library A |
| 5 | +// RUN: %target-swift-frontend -emit-module %t/src/API.swift \ |
| 6 | +// RUN: -module-name API -swift-version 5 -enable-library-evolution \ |
| 7 | +// RUN: -emit-module-path %t/API.swiftmodule \ |
| 8 | +// RUN: -emit-module-interface-path %t/API.swiftinterface |
| 9 | + |
| 10 | +// Build client with module |
| 11 | +// RUN: %target-swift-emit-silgen \ |
| 12 | +// RUN: -I %t \ |
| 13 | +// RUN: -disable-availability-checking \ |
| 14 | +// RUN: -module-name Client \ |
| 15 | +// RUN: -enable-experimental-feature PreconcurrencyConformances \ |
| 16 | +// RUN: %t/src/Client.swift -verify | %FileCheck %s |
| 17 | + |
| 18 | +// Delete swiftmodule to test building against swiftinterface |
| 19 | +// RUN: rm %t/API.swiftmodule |
| 20 | + |
| 21 | +// Build client from interface |
| 22 | +// RUN: %target-swift-emit-silgen \ |
| 23 | +// RUN: -I %t \ |
| 24 | +// RUN: -disable-availability-checking \ |
| 25 | +// RUN: -module-name Client \ |
| 26 | +// RUN: -enable-experimental-feature PreconcurrencyConformances \ |
| 27 | +// RUN: %t/src/Client.swift -verify | %FileCheck %s |
| 28 | + |
| 29 | +// REQUIRES: asserts |
| 30 | +// REQUIRES: concurrency |
| 31 | + |
| 32 | +//--- API.swift |
| 33 | +public func compute<T>(_: ((T) -> Void)?) {} |
| 34 | + |
| 35 | +public struct S<T> { |
| 36 | + public init() {} |
| 37 | + |
| 38 | + public func test<U>(_: ((T) -> U)?) {} |
| 39 | + |
| 40 | + public subscript(fn: () -> T) -> T { |
| 41 | + get { fn() } |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +//--- Client.swift |
| 46 | +import API |
| 47 | + |
| 48 | +@MainActor func test(_: Int?) { |
| 49 | +} |
| 50 | + |
| 51 | +// CHECK-LABEL: sil hidden [ossa] @$s6Client20testMainActorContextyyF : $@convention(thin) () -> () |
| 52 | +// CHECK: [[TEST_REF:%.*]] = function_ref @$s6Client4testyySiSgF : $@convention(thin) (Optional<Int>) -> () |
| 53 | +// CHECK-NEXT: [[TEST_FN:%.*]] = thin_to_thick_function [[TEST_REF]] : $@convention(thin) (Optional<Int>) -> () to $@callee_guaranteed (Optional<Int>) -> () |
| 54 | +// CHECK: [[THUNK:%.*]] = function_ref @$sSiSgIegy_AAIegy_TRScMTU : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> () |
| 55 | +// CHECK-NEXT: [[THUNKED_TEST_REF:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[TEST_FN]]) : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> () |
| 56 | +// CHECK-NEXT: [[OPTIONAL_TEST:%.*]] = enum $Optional<@callee_guaranteed (Optional<Int>) -> ()>, #Optional.some!enumelt, [[THUNKED_TEST_REF]] : $@callee_guaranteed (Optional<Int>) -> () |
| 57 | +// CHECK-NEXT: switch_enum [[OPTIONAL_TEST]] : $Optional<@callee_guaranteed (Optional<Int>) -> ()>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2 |
| 58 | +// CHECK: bb3([[UNWRAPPED_TEST_REF:%.*]] : @owned $Optional<@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> () for <Optional<Int>>>): |
| 59 | +// CHECK: [[COMPUTE_REF:%.*]] = function_ref @$s3API7computeyyyxcSglF : $@convention(thin) <τ_0_0> (@guaranteed Optional<@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> () for <τ_0_0>>) -> () |
| 60 | +// CHECK-NEXT: {{.*}} = apply [[COMPUTE_REF]]<Int?>([[UNWRAPPED_TEST_REF]]) : $@convention(thin) <τ_0_0> (@guaranteed Optional<@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> () for <τ_0_0>>) -> () |
| 61 | +@MainActor |
| 62 | +func testMainActorContext() { |
| 63 | + compute(test) // no warning |
| 64 | +} |
| 65 | + |
| 66 | +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiSgIegy_AAIegy_TRScMTU : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> () |
| 67 | +// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type |
| 68 | +// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 69 | +// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 70 | +// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor |
| 71 | +// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor |
| 72 | +// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF |
| 73 | +// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]]) |
| 74 | + |
| 75 | + |
| 76 | +// CHECK-LABEL: sil hidden [ossa] @$s6Client17testComplexGlobalyyyxSgScMYcclF : $@convention(thin) <U> (@guaranteed @callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U>) -> () |
| 77 | +func testComplexGlobal<U>(_ fn: @escaping @MainActor (U?) -> Void) { |
| 78 | + // CHECK: [[FN:%.*]] = copy_value %0 : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U> |
| 79 | + // CHECK-NEXT: [[SUBST_FN:%.*]] = convert_function [[FN]] : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U> to $@callee_guaranteed (@in_guaranteed Optional<U>) -> () |
| 80 | + // CHECK: [[FN_THUNK:%.*]] = function_ref @$sxSgIegn_AAIegn_lTRScMTU : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @guaranteed @callee_guaranteed (@in_guaranteed Optional<τ_0_0>) -> ()) -> () |
| 81 | + // CHECK-NEXT: [[THUNKED_FN:%.*]] = partial_apply [callee_guaranteed] [[FN_THUNK]]<U>([[SUBST_FN]]) : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @guaranteed @callee_guaranteed (@in_guaranteed Optional<τ_0_0>) -> ()) -> () |
| 82 | + // CHECK-NEXT: [[SUBST_THUNKED_FN:%.*]] = convert_function [[THUNKED_FN]] : $@callee_guaranteed (@in_guaranteed Optional<U>) -> () to $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U> |
| 83 | + // CHECK-NEXT: {{.*}} = enum $Optional<@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U>>, #Optional.some!enumelt, [[SUBST_THUNKED_FN]] : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U> |
| 84 | + compute(fn) |
| 85 | + // expected-warning@-1 {{converting function value of type '@MainActor (U?) -> Void' to '(U?) -> Void' loses global actor 'MainActor'; this is an error in Swift 6}} |
| 86 | + |
| 87 | + // CHECK: [[CLOSURE:%.*]] = function_ref @$s6Client17testComplexGlobalyyyxSgScMYcclFySiScMYccfU_ : $@convention(thin) (Int) -> () |
| 88 | + // CHECK-NEXT: [[CLOSURE_REF:%.*]] = thin_to_thick_function [[CLOSURE]] : $@convention(thin) (Int) -> () to $@callee_guaranteed (Int) -> () |
| 89 | + // CHECK: [[CLOSURE_THUNK:%.*]] = function_ref @$sSiIegy_SiIegy_TRScMTU : $@convention(thin) (Int, @guaranteed @callee_guaranteed (Int) -> ()) -> () |
| 90 | + // CHECK-NEXT: {{.*}} = partial_apply [callee_guaranteed] [[CLOSURE_THUNK]]([[CLOSURE_REF]]) : $@convention(thin) (Int, @guaranteed @callee_guaranteed (Int) -> ()) -> () |
| 91 | + compute { @MainActor (arg: Int) -> Void in |
| 92 | + // expected-warning@-1 {{converting function value of type '@MainActor (Int) -> Void' to '(Int) -> Void' loses global actor 'MainActor'; this is an error in Swift 6}} |
| 93 | + } |
| 94 | +} |
| 95 | + |
| 96 | +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sxSgIegn_AAIegn_lTRScMTU : $@convention(thin) <U> (@in_guaranteed Optional<U>, @guaranteed @callee_guaranteed (@in_guaranteed Optional<U>) -> ()) -> () |
| 97 | +// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type |
| 98 | +// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 99 | +// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 100 | +// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor |
| 101 | +// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor |
| 102 | +// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF |
| 103 | +// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]]) |
| 104 | + |
| 105 | +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiIegy_SiIegy_TRScMTU : $@convention(thin) (Int, @guaranteed @callee_guaranteed (Int) -> ()) -> () |
| 106 | +// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type |
| 107 | +// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 108 | +// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 109 | +// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor |
| 110 | +// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor |
| 111 | +// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF |
| 112 | +// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]]) |
| 113 | + |
| 114 | +// CHECK-LABEL: sil hidden [ossa] @$s6Client11testMembers1v1s2fnyx_3API1SVyxGSixScMYcctlF : $@convention(thin) <X> (@in_guaranteed X, @in_guaranteed S<X>, @guaranteed @callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> Int for <X>) -> () |
| 115 | +@MainActor |
| 116 | +func testMembers<X>(v: X, s: S<X>, fn: @escaping @MainActor (X) -> Int) { |
| 117 | + // CHECK: [[FN_COPY:%.*]] = copy_value %2 : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> Int for <X> |
| 118 | + // CHECK-NEXT: [[FN:%.*]] = convert_function [[FN_COPY]] : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> Int for <X> to $@callee_guaranteed (@in_guaranteed X) -> Int |
| 119 | + // CHECK: [[FN_THUNK:%.*]] = function_ref @$sxSiIegnd_xSiIegnd_lTRScMTU : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> Int) -> Int |
| 120 | + // CHECK-NEXT: [[THUNKED_FN:%.*]] = partial_apply [callee_guaranteed] [[FN_THUNK]]<X>([[FN]]) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> Int) -> Int |
| 121 | + // CHECK-NEXT: {{.*}} = convert_function [[THUNKED_FN]] : $@callee_guaranteed (@in_guaranteed X) -> Int to $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> Int for <X> |
| 122 | + s.test(fn) |
| 123 | + |
| 124 | + // CHECK: [[CLOSURE_REF:%.*]] = function_ref @$s6Client11testMembers1v1s2fnyx_3API1SVyxGSixScMYcctlFxyScMYcXEfU_ : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0 |
| 125 | + // CHECK-NEXT: [[V:%.*]] = alloc_stack $X |
| 126 | + // CHECK-NEXT: copy_addr %0 to [init] [[V]] : $*X |
| 127 | + // CHECK-NEXT: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_REF]]<X>([[V]]) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0 |
| 128 | + // CHECK-NEXT: [[SUBST_CLOSURE:%.*]] = convert_function [[CLOSURE]] : $@callee_guaranteed () -> @out X to $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> |
| 129 | + // CHECK-NEXT: [[NOESCAPE_SUBST_CLOSURE:%.*]] = convert_escape_to_noescape [not_guaranteed] [[SUBST_CLOSURE]] : $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> to $@noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> |
| 130 | + // CHECK-NEXT: [[CLOSURE:%.*]] = convert_function [[NOESCAPE_SUBST_CLOSURE]] : $@noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> to $@noescape @callee_guaranteed () -> @out X |
| 131 | + // CHECK: [[CLOSURE_THUNK_REF:%.*]] = function_ref @$sxIgr_xIgr_lTRScMTU : $@convention(thin) <τ_0_0> (@guaranteed @noescape @callee_guaranteed () -> @out τ_0_0) -> @out τ_0_0 |
| 132 | + // CHECK-NEXT: [[THUNKED_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_THUNK_REF]]<X>([[CLOSURE]]) : $@convention(thin) <τ_0_0> (@guaranteed @noescape @callee_guaranteed () -> @out τ_0_0) -> @out τ_0_0 |
| 133 | + // CHECK-NEXT: [[SUBST_THUNKED_CLOSURE:%.*]] = convert_function [[THUNKED_CLOSURE]] : $@callee_guaranteed () -> @out X to $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> |
| 134 | + // CHECK-NEXT: [[THUNKED_CLOSURE:%.*]] = convert_escape_to_noescape [not_guaranteed] [[SUBST_THUNKED_CLOSURE]] : $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> to $@noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> |
| 135 | + // CHECK: [[SETTER_REF:%.*]] = function_ref @$s3API1SVyxxyXEcig : $@convention(method) <τ_0_0> (@guaranteed @noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_0_0>, @in_guaranteed S<τ_0_0>) -> @out τ_0_0 |
| 136 | + // CHECK-NEXT: %41 = apply [[SETTER_REF]]<X>({{.*}}, [[THUNKED_CLOSURE]], {{.*}}) : $@convention(method) <τ_0_0> (@guaranteed @noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_0_0>, @in_guaranteed S<τ_0_0>) -> @out τ_0_0 |
| 137 | + _ = s[{ @MainActor in v }] |
| 138 | + |
| 139 | + // CHECK: [[TEST_REF:%.*]] = function_ref @$s6Client4testyySiSgF : $@convention(thin) (Optional<Int>) -> () |
| 140 | + // CHECK-NEXT: [[TEST:%.*]] = thin_to_thick_function [[TEST_REF]] : $@convention(thin) (Optional<Int>) -> () to $@callee_guaranteed (Optional<Int>) -> () |
| 141 | + // CHECK: [[TEST_THUNK_REF:%.*]] = function_ref @$sSiSgIegy_AAIegy_TRScMTU : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> () |
| 142 | + // CHECK-NEXT: {{.*}} = partial_apply [callee_guaranteed] [[TEST_THUNK_REF]]([[TEST]]) : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> () |
| 143 | + S().test(test) |
| 144 | +} |
| 145 | + |
| 146 | +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sxSiIegnd_xSiIegnd_lTRScMTU : $@convention(thin) <X> (@in_guaranteed X, @guaranteed @callee_guaranteed (@in_guaranteed X) -> Int) -> Int |
| 147 | +// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type |
| 148 | +// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 149 | +// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 150 | +// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor |
| 151 | +// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor |
| 152 | +// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF |
| 153 | +// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]]) |
| 154 | + |
| 155 | +// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sxIgr_xIgr_lTRScMTU : $@convention(thin) <X> (@guaranteed @noescape @callee_guaranteed () -> @out X) -> @out X |
| 156 | +// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type |
| 157 | +// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 158 | +// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor |
| 159 | +// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor |
| 160 | +// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor |
| 161 | +// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF |
| 162 | +// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]]) |
0 commit comments