// RUN: %target-swift-frontend -O %s -emit-sil | %FileCheck %s // Make sure that we can dig all the way through the class hierarchy and // protocol conformances. // CHECK-LABEL: sil @$s28devirt_inherited_conformance6driveryyF : $@convention(thin) () -> () { // CHECK: bb0 // CHECK: [[UNKNOWN2a:%.*]] = function_ref @unknown2a : $@convention(thin) () -> () // CHECK: apply [[UNKNOWN2a]] // CHECK: apply [[UNKNOWN2a]] // CHECK: [[UNKNOWN3a:%.*]] = function_ref @unknown3a : $@convention(thin) () -> () // CHECK: apply [[UNKNOWN3a]] // CHECK: apply [[UNKNOWN3a]] // CHECK: return @_silgen_name("unknown1a") func unknown1a() -> () @_silgen_name("unknown1b") func unknown1b() -> () @_silgen_name("unknown2a") func unknown2a() -> () @_silgen_name("unknown2b") func unknown2b() -> () @_silgen_name("unknown3a") func unknown3a() -> () @_silgen_name("unknown3b") func unknown3b() -> () struct Int32 {} protocol P { // We do not specialize typealias's correctly now. //typealias X func doSomething(_ x : Int32) // This exposes a SILGen bug. FIXME: Fix up this test in the future. // class func doSomethingMeta() } class B : P { // We do not specialize typealias's correctly now. //typealias X = B func doSomething(_ x : Int32) { unknown1a() } // See comment in protocol P //class func doSomethingMeta() { // unknown1b() //} } class B2 : B { // When we have covariance in protocols, change this to B2. // We do not specialize typealias correctly now. //typealias X = B override func doSomething(_ x : Int32) { unknown2a() } // See comment in protocol P //override class func doSomethingMeta() { // unknown2b() //} } class B3 : B { // When we have covariance in protocols, change this to B3. // We do not specialize typealias correctly now. //typealias X = B override func doSomething(_ x : Int32) { unknown3a() } // See comment in protocol P //override class func doSomethingMeta() { // unknown3b() //} } func WhatShouldIDo(_ t : T, _ x : Int32) { t.doSomething(x) } func WhatShouldIDo2(_ p : P, _ x : Int32) { p.doSomething(x) } public func driver() -> () { let b2 = B2() let b3 = B3() let x = Int32() WhatShouldIDo(b2, x) WhatShouldIDo2(b2, x) WhatShouldIDo(b3, x) WhatShouldIDo2(b3, x) } // Test that inherited conformances work properly with // standard operators like == and custom operators like --- // Comparable is similar to Equatable, but uses a usual method // instead of an operator. public protocol Comparable { func compare(_: Self, _: Self) -> Bool } // Define a custom operator to be used instead of == infix operator --- // Simple is a protocol that simply defines an operator and // a few methods with different number of arguments. public protocol Simple { func foo(_: Self) -> Bool func boo(_: Self, _: Self) -> Bool static func ---(_: Self, _: Self) -> Bool } public class C: Equatable, Comparable, Simple { public func compare(_ c1:C, _ c2:C) -> Bool { return c1 == c2 } public func foo(_ c:C) -> Bool { return true } public func boo(_ c1:C, _ c2:C) -> Bool { return false } } // D inherits a bunch of conformances from C. // We want to check that compiler can handle // them properly and is able to devirtualize // them. public class D: C { } public func ==(lhs: C, rhs: C) -> Bool { return true } public func ---(lhs: C, rhs: C) -> Bool { return true } public func compareEquals(_ x: T, _ y:T) -> Bool { return x == y } public func compareMinMinMin(_ x: T, _ y:T) -> Bool { return x --- y } public func compareComparable(_ x: T, _ y:T) -> Bool { return x.compare(x, y) } // Check that a call of inherited Equatable.== can be devirtualized. // CHECK-LABEL: sil @$s28devirt_inherited_conformance17testCompareEqualsSbyF : $@convention(thin) () -> Bool { // CHECK: bb0 // CHECK-NEXT: integer_literal $Builtin.Int1, -1 // CHECK-NEXT: struct $Bool // CHECK: return // CHECK: } public func testCompareEquals() -> Bool { return compareEquals(D(), D()) } // Check that a call of inherited Simple.== can be devirtualized. // CHECK-LABEL: sil @$s28devirt_inherited_conformance014testCompareMinfF0SbyF : $@convention(thin) () -> Bool { // CHECK: bb0 // CHECK-NEXT: integer_literal $Builtin.Int1, -1 // CHECK-NEXT: struct $Bool // CHECK: return public func testCompareMinMinMin() -> Bool { return compareMinMinMin(D(), D()) } // Check that a call of inherited Comparable.== can be devirtualized. // CHECK-LABEL: sil @$s28devirt_inherited_conformance21testCompareComparableSbyF : $@convention(thin) () -> Bool { // CHECK: bb0 // CHECK-NEXT: integer_literal $Builtin.Int1, -1 // CHECK-NEXT: struct $Bool // CHECK: return public func testCompareComparable() -> Bool { return compareComparable(D(), D()) } public func BooCall(_ x:T, _ y:T) -> Bool { return x.boo(y, y) } // Check that a call of inherited Simple.boo can be devirtualized. // CHECK-LABEL: sil @$s28devirt_inherited_conformance11testBooCallSbyF : $@convention(thin) () -> Bool { // CHECK: bb0 // CHECK-NEXT: integer_literal $Builtin.Int1, 0 // CHECK-NEXT: struct $Bool // CHECK: return public func testBooCall() -> Bool { return BooCall(D(), D()) }