// RUN: %target-swift-frontend -parse-as-library -O -wmo -emit-sil %s | %FileCheck %s // RUN: %target-swift-frontend -parse-as-library -Osize -wmo -emit-sil %s | %FileCheck %s // REQUIRES: objc_interop // This is an end-to-end test to ensure that the optimizer devirtualizes // calls to a protocol composition type. public class ClassA { } protocol ProtocolA { func foo() -> Int } protocol ProtocolB { func bar() -> Int } public class ClassB: ClassA { func foo() -> Int { return 10 } } extension ClassB: ProtocolA { } public class ClassC: ClassA { func foo() -> Int { return 10 } } extension ClassC: ProtocolA { } public class ClassD { } public class ClassE : ClassD { func foo() -> Int { return 10 } } extension ClassE: ProtocolA { } public class ClassF { func foo() -> Int { return 10 } func bar() -> Int { return 10 } } extension ClassF: ProtocolA, ProtocolB { } public class ClassG { func foo() -> Int { return 10 } func bar() -> Int { return 10 } } extension ClassG: ProtocolA, ProtocolB { } public class ClassH { typealias type = ClassD } func shouldOptimize1(_ x: ClassA & ProtocolA) -> Int { return x.foo() } func shouldOptimize2(_ x: ClassD & ProtocolA) -> Int { return x.foo() } func shouldOptimize3(_ x: ProtocolA & ProtocolB) -> Int { return x.foo() + x.bar() } func shouldOptimize4(_ x: ProtocolA & ProtocolB) -> Int { return x.foo() + x.bar() } func shouldOptimize5(_ x: ClassH.type & ProtocolA) -> Int { return x.foo() } //CHECK: entryPoint1 //CHECK-NOT: init_existential_ref //CHECK-NOT: open_existential_ref //CHECK-NOT: witness_method //CHECK: return public func entryPoint1(c: ClassB) -> Int { return shouldOptimize1(c) } // TODO: create SR -- this causes a crash on master too //public func entryPoint2(c: ClassC) -> Int { // return shouldOptimize1(c) //} //CHECK: entryPoint3 //CHECK-NOT: init_existential_ref //CHECK-NOT: open_existential_ref //CHECK-NOT: witness_method //CHECK: return public func entryPoint3(c: ClassE) -> Int { return shouldOptimize2(c) } //CHECK: entryPoint4 //CHECK-NOT: init_existential_ref //CHECK-NOT: open_existential_ref //CHECK-NOT: witness_method //CHECK: return public func entryPoint4(c: ClassF) -> Int { return shouldOptimize3(c) } //CHECK: entryPoint5 //CHECK-NOT: init_existential_ref //CHECK-NOT: open_existential_ref //CHECK-NOT: witness_method //CHECK: return public func entryPoint5(c: ClassG) -> Int { return shouldOptimize4(c) } //CHECK: entryPoint6 //CHECK-NOT: init_existential_ref //CHECK-NOT: open_existential_ref //CHECK-NOT: witness_method //CHECK: return public func entryPoint6(c: ClassE) -> Int { return shouldOptimize5(c) }