Skip to content

Commit 084b0e0

Browse files
committed
SILGen: Strip __owned from parameter types when emitting SE-0110 tuple splat
Instead of using composeInput(), build a tuple type containing the element types only, dropping ownership qualifiers and asserting that there are no inout or vararg elements. This is correct because we already promote +0 values to +1, or clean up +1 values that are only used as +0 as needed. Fixes <rdar://problem/44915136>.
1 parent 8061358 commit 084b0e0

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

lib/SILGen/SILGenPoly.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -896,12 +896,18 @@ namespace {
896896
}
897897
auto outputOrigType = AbstractionPattern::getTuple(outputOrigTypes);
898898

899-
// Build the substituted output tuple type.
899+
// Build the substituted output tuple type. Note that we deliberately
900+
// don't use composeInput() because we want to drop ownership
901+
// qualifiers.
902+
SmallVector<TupleTypeElt, 8> elts;
903+
for (auto param : outputSubstTypes) {
904+
assert(!param.isVariadic());
905+
assert(!param.isInOut());
906+
elts.emplace_back(param.getParameterType());
907+
}
900908
auto outputSubstType = cast<TupleType>(
901-
AnyFunctionType::composeInput(SGF.getASTContext(),
902-
outputSubstTypes,
903-
/*canonicalVararg=*/true)
904-
->getCanonicalType());
909+
TupleType::get(elts, SGF.getASTContext())
910+
->getCanonicalType());
905911

906912
// Translate the input tuple value into the output tuple value. Note
907913
// that the output abstraction pattern is a tuple, and we explode tuples

test/Interpreter/FunctionConversion.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,25 @@ FunctionConversionTestSuite.test("CollectionUpCastsWithHashableInFuncParameters"
302302
expectEqual(rdar35702810_set_hashable(type: B.self, fn_set), 42)
303303
}
304304

305+
func takesTwo(_ fn: ((AnyObject, AnyObject)) -> (),
306+
_ a: AnyObject,
307+
_ b: AnyObject) {
308+
fn((a, b))
309+
}
310+
311+
func takesTwoGeneric<T>(_ fn: (T) -> (), _ a: T) {
312+
fn(a)
313+
}
314+
315+
FunctionConversionTestSuite.test("SE0110") {
316+
func callback1(_: AnyObject, _: AnyObject) {}
317+
func callback2(_: __owned AnyObject, _: __owned AnyObject) {}
318+
319+
takesTwo(callback1, LifetimeTracked(0), LifetimeTracked(0))
320+
takesTwo(callback2, LifetimeTracked(0), LifetimeTracked(0))
321+
322+
takesTwoGeneric(callback1, (LifetimeTracked(0), LifetimeTracked(0)))
323+
takesTwoGeneric(callback2, (LifetimeTracked(0), LifetimeTracked(0)))
324+
}
325+
305326
runAllTests()

test/SILGen/function_conversion_se0110.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,24 @@ func givesNoneGeneric(_ fn: () -> ()) {
3636

3737
// reabstraction thunk helper from @callee_guaranteed () -> () to @escaping @callee_guaranteed (@in_guaranteed ()) -> ()
3838
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$sIg_ytIegn_TR : $@convention(thin) (@in_guaranteed (), @noescape @callee_guaranteed () -> ()) -> ()
39+
40+
41+
// "Tuple splat" still works if there are __owned parameters.
42+
// Make sure the memory management is correct also.
43+
44+
// CHECK-LABEL: sil hidden @$s19function_conversion17takesTwoAnyObjectyyyyXl_yXlt_tXEF : $@convention(thin) (@noescape @callee_guaranteed (@guaranteed AnyObject, @guaranteed AnyObject) -> ()) -> ()
45+
func takesTwoAnyObject(_: ((AnyObject, AnyObject)) -> ()) {}
46+
47+
// CHECK-LABEL: sil hidden @$s19function_conversion22givesTwoAnyObjectOwnedyyyyXln_yXlntXEF : $@convention(thin) (@noescape @callee_guaranteed (@owned AnyObject, @owned AnyObject) -> ()) -> ()
48+
func givesTwoAnyObjectOwned(_ fn: (__owned AnyObject, __owned AnyObject) -> ()) {
49+
takesTwoAnyObject(fn)
50+
}
51+
52+
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$syXlyXlIgxx_yXlyXlIeggg_TR : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject, @noescape @callee_guaranteed (@owned AnyObject, @owned AnyObject) -> ()) -> () {
53+
// CHECK: bb0(%0 : @guaranteed $AnyObject, %1 : @guaranteed $AnyObject, %2 : @trivial $@noescape @callee_guaranteed (@owned AnyObject, @owned AnyObject) -> ()):
54+
// CHECK-NEXT: [[FIRST:%.*]] = copy_value %0
55+
// CHECK-NEXT: [[SECOND:%.*]] = copy_value %1
56+
// CHECK-NEXT: apply %2([[FIRST]], [[SECOND]]) : $@noescape @callee_guaranteed (@owned AnyObject, @owned AnyObject) -> ()
57+
// CHECK-NEXT: [[RESULT:%.*]] = tuple ()
58+
// CHECK-NEXT: return [[RESULT]] : $()
59+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)