Files
swift-mirror/test/Interpreter/dynamic_self.swift
Doug Gregor 12c064d501 IR generation for DynamicSelf method invocations on existentials.
When projecting an existential into an opened archetype, bind the
archetype with metadata and witness tables extracted from the
existential. Tweak SILGen so that it doesn't destroy the opened
archetype value an extra two times.

Use an executable testcase to ensure end-to-end operation, because we
still don't have a parsable form existential projection to opened
archetype instructions.



Swift SVN r13755
2014-02-10 18:47:24 +00:00

98 lines
1.9 KiB
Swift

// RUN: %target-run-simple-swift | FileCheck %s
// Test IR generation via execution for DynamicSelf.
protocol P {
func f() -> DynamicSelf
func g() -> DynamicSelf
}
@class_protocol protocol CP {
func f() -> DynamicSelf
func g() -> DynamicSelf
}
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")
}
destructor() {
println("Destroying C")
}
func f() -> DynamicSelf {
println("C.f()")
return self
}
func g() -> DynamicSelf {
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")