mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
209 lines
5.1 KiB
Swift
209 lines
5.1 KiB
Swift
// 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 : P>(_ 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<T:Equatable>(_ x: T, _ y:T) -> Bool {
|
|
return x == y
|
|
}
|
|
|
|
public func compareMinMinMin<T:Simple>(_ x: T, _ y:T) -> Bool {
|
|
return x --- y
|
|
}
|
|
|
|
|
|
public func compareComparable<T:Comparable>(_ 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<T:Simple>(_ 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())
|
|
}
|