Skip to content

Commit dcecf52

Browse files
committed
[SILOptimizer] TypeWrappers/NFC: Add tests for convenience initializers of wrapped types
1 parent 3fd5ed5 commit dcecf52

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

test/Interpreter/Inputs/type_wrapper_defs.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,35 @@ public class UserDefinedInitWithConditionalTest<T> {
271271
print(self.val)
272272
}
273273
}
274+
275+
@Wrapper
276+
public class ClassWithConvenienceInit<T> {
277+
public var a: T?
278+
public var b: String
279+
280+
init(a: T?, b: String) {
281+
// Just to test that conditionals work properly
282+
if let a {
283+
self.a = a
284+
} else {
285+
self.a = nil
286+
}
287+
288+
self.b = b
289+
}
290+
291+
public convenience init() {
292+
self.init(a: nil)
293+
print(self.a)
294+
print(self.b)
295+
}
296+
297+
public convenience init(a: T?) {
298+
self.init(a: a, b: "<placeholder>")
299+
print(self.a)
300+
print(self.b)
301+
302+
self.b = "<modified>"
303+
print(self.b)
304+
}
305+
}

test/Interpreter/type_wrappers.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,3 +551,39 @@ do {
551551
// CHECK-NEXT: nil
552552
}
553553
}
554+
555+
do {
556+
let test1 = ClassWithConvenienceInit(a: [1, 2, 3])
557+
// CHECK: in getter
558+
// CHECK-NEXT: [1, 2, 3]
559+
// CHECK-NEXT: in getter
560+
// CHECK-NEXT: <placeholder>
561+
// CHECK-NEXT: in setter => <modified>
562+
// CHECK-NEXT: in getter
563+
// CHECK-NEXT: <modified>
564+
565+
func test<T>(_ v: T) {
566+
let test1 = ClassWithConvenienceInit<(Int, String, T)>()
567+
test1.a = (-1, "ultimate question", v)
568+
print(test1.a)
569+
}
570+
571+
test((a: 1, b: 2.0, c: 3))
572+
// -> from init(a: T?)
573+
// CHECK: in getter
574+
// CHECK-NEXT: nil
575+
// CHECK-NEXT: in getter
576+
// CHECK-NEXT: <placeholder>
577+
// CHECK-NEXT: in setter => <modified>
578+
// CHECK-NEXT: in getter
579+
// CHECK-NEXT: <modified>
580+
// -> from init()
581+
// CHECK-NEXT: in getter
582+
// CHECK-NEXT: nil
583+
// CHECK-NEXT: in getter
584+
// CHECK-NEXT: <modified>
585+
// -> from test<T>(_: T)
586+
// CHECK-NEXT: in setter => Optional((-1, "ultimate question", (a: 1, b: 2.0, c: 3)))
587+
// CHECK-NEXT: in getter
588+
// CHECK-NEXT: Optional((-1, "ultimate question", (a: 1, b: 2.0, c: 3)))
589+
}

test/SILOptimizer/type_wrapper_init_transform.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,40 @@ class TestConditionalInjection<T> {
293293
}
294294
}
295295
}
296+
297+
/// Make sure that convenience initializers don't get _storage variable injected and don't produce any assign_by_wrapper instructions
298+
@Wrapper
299+
class ClassWithConvenienceInit<T> {
300+
var a: T?
301+
var b: String
302+
303+
init(a: T?, b: String) {
304+
self.a = a
305+
self.b = b
306+
}
307+
308+
// CHECK-LABEL: sil hidden [ossa] @$s4test24ClassWithConvenienceInitC1aACyxGxSg_tcfC
309+
// CHECK-NOT: {{.*}} alloc_stack [lexical] $(b: Optional<T>), var, name "_storage", implicit
310+
// CHECK-NOT: assign_by_wrapper {{.*}}
311+
312+
convenience init(a: T? = nil) {
313+
self.init(a: a, b: "<placeholder>")
314+
315+
// CHECK: [[A_GETTER:%.*]] = class_method [[SELF:%.*]] : $ClassWithConvenienceInit<T>, #ClassWithConvenienceInit.a!getter
316+
// CHECK-NEXT: {{.*}} = apply [[A_GETTER]]<T>({{.*}})
317+
_ = self.a
318+
// CHECK: [[B_GETTER:%.*]] = class_method [[SELF:%.*]] : $ClassWithConvenienceInit<T>, #ClassWithConvenienceInit.b!getter
319+
// CHECK-NEXT: {{.*}} = apply [[B_GETTER]]<T>({{.*}})
320+
_ = self.b
321+
322+
// CHECK: [[A_SETTER:%.*]] = class_method [[SELF:%.*]] : $ClassWithConvenienceInit<T>, #ClassWithConvenienceInit.a!setter
323+
// CHECK-NEXT: {{.*}} = apply [[A_SETTER]]<T>({{.*}})
324+
self.a = a
325+
326+
if let a {
327+
// CHECK: [[B_SETTER:%.*]] = class_method [[SELF:%.*]] : $ClassWithConvenienceInit<T>, #ClassWithConvenienceInit.b!setter
328+
// CHECK-NEXT: {{.*}} = apply [[B_SETTER]]<T>({{.*}})
329+
self.b = "ultimate question"
330+
}
331+
}
332+
}

0 commit comments

Comments
 (0)