mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
This only tackles the protocol case (<rdar://problem/17510790>); it does not yet generalize to an arbitrary "class" requirement on either existentials or generics. Swift SVN r19896
98 lines
1.8 KiB
Swift
98 lines
1.8 KiB
Swift
// RUN: %target-run-simple-swift | FileCheck %s
|
|
|
|
// Test IR generation via execution for Self.
|
|
|
|
protocol P {
|
|
func f() -> Self
|
|
func g() -> Self
|
|
}
|
|
|
|
protocol CP : class {
|
|
func f() -> Self
|
|
func g() -> Self
|
|
}
|
|
|
|
func callDynamicSelfExistential(p: P) {
|
|
println("Before first call")
|
|
var p2 = p.f()
|
|
println("Between calls")
|
|
p2.g()
|
|
println("After second call")
|
|
}
|
|
|
|
func callDynamicSelfClassExistential(cp: CP) {
|
|
println("Before first call")
|
|
var cp2 = cp.f()
|
|
println("Between calls")
|
|
cp2.g()
|
|
println("After second call")
|
|
}
|
|
|
|
struct S : P {
|
|
func f() -> S {
|
|
println("S.f()")
|
|
return self
|
|
}
|
|
|
|
func g() -> S {
|
|
println("S.g()")
|
|
return self
|
|
}
|
|
}
|
|
|
|
class C : P, CP {
|
|
init() {
|
|
println("Allocating C")
|
|
}
|
|
|
|
deinit {
|
|
println("Destroying C")
|
|
}
|
|
|
|
func f() -> Self {
|
|
println("C.f()")
|
|
return self
|
|
}
|
|
|
|
func g() -> Self {
|
|
println("C.g()")
|
|
return self
|
|
}
|
|
}
|
|
|
|
println("-------------------------------")
|
|
|
|
// CHECK: S() as non-class existential
|
|
println("S() as non-class existential")
|
|
// CHECK-NEXT: Before first call
|
|
// CHECK-NEXT: S.f()
|
|
// CHECK-NEXT: Between calls
|
|
// CHECK-NEXT: S.g()
|
|
// CHECK-NEXT: After second call
|
|
callDynamicSelfExistential(S())
|
|
|
|
// CHECK-NEXT: C() as non-class existential
|
|
println("C() as non-class existential")
|
|
// CHECK-NEXT: Allocating C
|
|
// CHECK-NEXT: Before first call
|
|
// CHECK-NEXT: C.f()
|
|
// CHECK-NEXT: Between calls
|
|
// CHECK-NEXT: C.g()
|
|
// CHECK-NEXT: After second call
|
|
// CHECK-NEXT: Destroying C
|
|
callDynamicSelfExistential(C())
|
|
|
|
// CHECK-NEXT: C() as class existential
|
|
println("C() as class existential")
|
|
// CHECK-NEXT: Allocating C
|
|
// CHECK-NEXT: Before first call
|
|
// CHECK-NEXT: C.f()
|
|
// CHECK-NEXT: Between calls
|
|
// CHECK-NEXT: C.g()
|
|
// CHECK-NEXT: After second call
|
|
// CHECK-NEXT: Destroying C
|
|
callDynamicSelfClassExistential(C())
|
|
|
|
// CHECK-NEXT: Done
|
|
println("Done")
|