mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This prevents us from seeing a less useful error message from SILGen further down the line. Also fix a bug where @objc without importing Foundation was not diagnosed after the first top-level form. Some tests were relying on this behavior, so fix those tests, either by splitting off the objc parts of the test, or just by passing the -disable-objc-attr-requires-foundation-module flag. Fixes <rdar://problem/20660270>. Swift SVN r29359
156 lines
3.4 KiB
Swift
156 lines
3.4 KiB
Swift
// RUN: %target-run-simple-swift | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
|
|
// REQUIRES: executable_test
|
|
|
|
// Note: JIT mode is checked in Interpreter/protocol_lookup_jit.swift.
|
|
|
|
protocol Fooable {
|
|
func foo()
|
|
}
|
|
|
|
struct S: Fooable {
|
|
func foo() { print("S") }
|
|
}
|
|
|
|
class C: Fooable {
|
|
func foo() { print("C") }
|
|
}
|
|
|
|
class D: C {
|
|
override func foo() { print("D") }
|
|
}
|
|
|
|
class E: D {
|
|
override func foo() { print("E") }
|
|
}
|
|
|
|
struct X {}
|
|
|
|
extension Int: Fooable {
|
|
func foo() { print("Int") }
|
|
}
|
|
|
|
func fooify<T>(x: T) {
|
|
if let foo = x as? Fooable {
|
|
foo.foo()
|
|
} else {
|
|
print("not fooable")
|
|
}
|
|
}
|
|
|
|
struct G<T>: Fooable {
|
|
func foo() { print("G") }
|
|
}
|
|
|
|
struct H<T> {}
|
|
|
|
fooify(1) // CHECK: Int
|
|
fooify(2) // CHECK-NEXT: Int
|
|
fooify(S()) // CHECK-NEXT: S
|
|
fooify(S()) // CHECK-NEXT: S
|
|
fooify(C()) // CHECK-NEXT: C
|
|
fooify(C()) // CHECK-NEXT: C
|
|
fooify(D()) // CHECK-NEXT: D
|
|
fooify(D()) // CHECK-NEXT: D
|
|
fooify(E()) // CHECK-NEXT: E
|
|
fooify(E()) // CHECK-NEXT: E
|
|
fooify(X()) // CHECK-NEXT: not fooable
|
|
fooify(X()) // CHECK-NEXT: not fooable
|
|
fooify(G<Int>()) // CHECK-NEXT: G
|
|
fooify(G<Float>()) // CHECK-NEXT: G
|
|
fooify(G<Int>()) // CHECK-NEXT: G
|
|
fooify(H<Int>()) // CHECK-NEXT: not fooable
|
|
fooify(H<Float>()) // CHECK-NEXT: not fooable
|
|
fooify(H<Int>()) // CHECK-NEXT: not fooable
|
|
|
|
// TODO: generics w/ dependent witness tables
|
|
|
|
// Check casts from existentials.
|
|
|
|
fooify(1 as Any) // CHECK: Int
|
|
fooify(2 as Any) // CHECK-NEXT: Int
|
|
fooify(S() as Any) // CHECK-NEXT: S
|
|
fooify(S() as Any) // CHECK-NEXT: S
|
|
fooify(C() as Any) // CHECK-NEXT: C
|
|
fooify(C() as Any) // CHECK-NEXT: C
|
|
fooify(D() as Any) // CHECK-NEXT: D
|
|
fooify(D() as Any) // CHECK-NEXT: D
|
|
fooify(E() as Any) // CHECK-NEXT: E
|
|
fooify(E() as Any) // CHECK-NEXT: E
|
|
fooify(X() as Any) // CHECK-NEXT: not fooable
|
|
fooify(X() as Any) // CHECK-NEXT: not fooable
|
|
fooify(G<Int>() as Any) // CHECK-NEXT: G
|
|
fooify(G<Float>() as Any) // CHECK-NEXT: G
|
|
fooify(G<Int>() as Any) // CHECK-NEXT: G
|
|
fooify(H<Int>() as Any) // CHECK-NEXT: not fooable
|
|
fooify(H<Float>() as Any) // CHECK-NEXT: not fooable
|
|
fooify(H<Int>() as Any) // CHECK-NEXT: not fooable
|
|
|
|
protocol Barrable {
|
|
func bar()
|
|
}
|
|
extension Int: Barrable {
|
|
func bar() { print("Int.bar") }
|
|
}
|
|
|
|
let foo: Fooable = 2
|
|
if let bar = foo as? Barrable {
|
|
bar.bar() // CHECK-NEXT: Int.bar
|
|
} else {
|
|
print("not barrable")
|
|
}
|
|
|
|
let foo2: Fooable = S()
|
|
if let bar2 = foo2 as? Barrable {
|
|
bar2.bar()
|
|
} else {
|
|
print("not barrable") // CHECK-NEXT: not barrable
|
|
}
|
|
|
|
protocol Runcible: class {
|
|
func runce()
|
|
}
|
|
|
|
extension C: Runcible {
|
|
func runce() { print("C") }
|
|
}
|
|
|
|
let c1: AnyObject = C()
|
|
let c2: Any = C()
|
|
if let fruncible = c1 as? protocol<Fooable, Runcible> {
|
|
fruncible.foo() // CHECK-NEXT: C
|
|
fruncible.runce() // CHECK-NEXT: C
|
|
} else {
|
|
print("not fooable and runcible")
|
|
}
|
|
if let fruncible = c2 as? protocol<Fooable, Runcible> {
|
|
fruncible.foo() // CHECK-NEXT: C
|
|
fruncible.runce() // CHECK-NEXT: C
|
|
} else {
|
|
print("not fooable and runcible")
|
|
}
|
|
|
|
// Protocol lookup for metatypes.
|
|
protocol StaticFoo {
|
|
static func foo() -> String
|
|
}
|
|
|
|
class StaticBar {
|
|
class func mightHaveFoo() -> String {
|
|
if let selfAsFoo = self as? StaticFoo.Type {
|
|
return selfAsFoo.foo()
|
|
} else {
|
|
return "no Foo for you"
|
|
}
|
|
}
|
|
}
|
|
|
|
class StaticWibble : StaticBar, StaticFoo {
|
|
static func foo() -> String { return "StaticWibble.foo" }
|
|
}
|
|
|
|
// CHECK: no Foo for you
|
|
print(StaticBar.mightHaveFoo())
|
|
|
|
// CHECK: StaticWibble.foo
|
|
print(StaticWibble.mightHaveFoo())
|