// RUN: %target-typecheck-verify-swift protocol Fooable { func foo() } protocol Barable { func bar() } extension Int : Fooable, Barable { func foo() {} func bar() {} } extension Float32 : Barable { func bar() {} } func f0(_: Barable) {} func f1(_ x: Fooable & Barable) {} func f2(_: Float) {} let nilFunc: Optional<(Barable) -> ()> = nil func g(_: (Barable & Fooable) -> ()) {} protocol Classable : AnyObject {} class SomeArbitraryClass {} func fc0(_: Classable) {} func fc1(_: Fooable & Classable) {} func fc2(_: AnyObject) {} func fc3(_: SomeArbitraryClass) {} func gc(_: (Classable & Fooable) -> ()) {} var i : Int var f : Float var b : Barable //===----------------------------------------------------------------------===// // Conversion to and among existential types //===----------------------------------------------------------------------===// f0(i) f0(f) f0(b) f1(i) f1(f) // expected-error{{argument type 'Float' does not conform to expected type 'Fooable'}} f1(b) // expected-error{{argument type 'any Barable' does not conform to expected type 'Fooable'}} //===----------------------------------------------------------------------===// // Subtyping //===----------------------------------------------------------------------===// g(f0) // okay (subtype) g(f1) // okay (exact match) g(f2) // expected-error{{cannot convert value of type '(Float) -> ()' to expected argument type '(any Barable & Fooable) -> ()'}} g(nilFunc ?? f0) gc(fc0) // okay gc(fc1) // okay gc(fc2) // okay gc(fc3) // expected-error{{cannot convert value of type '(SomeArbitraryClass) -> ()' to expected argument type '(any Classable & Fooable) -> ()'}} // rdar://problem/19600325 func getAnyObject() -> AnyObject? { return SomeArbitraryClass() } func castToClass(_ object: Any) -> SomeArbitraryClass? { return object as? SomeArbitraryClass } _ = getAnyObject().map(castToClass) _ = { (_: Any) -> Void in return } as ((Int) -> Void) let _: (Int) -> Void = { (_: Any) -> Void in return } let _: () -> Any = { () -> Int in return 0 } let _: () -> Int = { () -> String in // expected-error {{declared closure result 'String' is incompatible with contextual type 'Int'}} return "" } //===----------------------------------------------------------------------===// // Members of archetypes //===----------------------------------------------------------------------===// func id(_ t: T) -> T { return t } protocol Initable { init() } protocol P : Initable { func bar(_ x: Int) mutating func mut(_ x: Int) static func tum() typealias E = Int typealias F = Self.E typealias G = Array } protocol ClassP : class { func bas(_ x: Int) func quux(_ x: Int) } class ClassC : ClassP { func bas(_ x: Int) {} } extension ClassP { func quux(_ x: Int) {} func bing(_ x: Int) {} } func generic(_ t: T) { var t = t // Instance member of archetype let _: (Int) -> () = id(t.bar) let _: () = id(t.bar(0)) // Static member of archetype metatype let _: () -> () = id(T.tum) // Instance member of archetype metatype let _: (T) -> (Int) -> () = id(T.bar) let _: (Int) -> () = id(T.bar(t)) _ = t.mut // expected-error{{cannot reference 'mutating' method as function value}} _ = t.tum // expected-error{{static member 'tum' cannot be used on instance of type 'T'}} } func genericClassP(_ t: T) { // Instance member of archetype) let _: (Int) -> () = id(t.bas) let _: () = id(t.bas(0)) // Instance member of archetype metatype) let _: (T) -> (Int) -> () = id(T.bas) let _: (Int) -> () = id(T.bas(t)) let _: () = id(T.bas(t)(1)) } func genericClassC(_ c: C) { // Make sure that we can find members of protocol extensions // on a class-bound archetype let _ = c.bas(123) let _ = c.quux(123) let _ = c.bing(123) } //===----------------------------------------------------------------------===// // Members of existentials //===----------------------------------------------------------------------===// func existential(_ p: P) { var p = p // Fully applied mutating method p.mut(1) _ = p.mut // expected-error{{cannot reference 'mutating' method as function value}} // Instance member of existential) let _: (Int) -> () = id(p.bar) let _: () = id(p.bar(0)) // Static member of existential metatype) let _: () -> () = id(type(of: p).tum) } func staticExistential(_ p: P.Type, pp: P.Protocol) { let _ = p() // expected-error{{initializing from a metatype value must reference 'init' explicitly}} let _ = p().bar // expected-error{{initializing from a metatype value must reference 'init' explicitly}} let _ = p().bar(1) // expected-error{{initializing from a metatype value must reference 'init' explicitly}} let ppp: P = p.init() _ = pp() // expected-error{{value of type '(any P).Type' is a protocol; it cannot be instantiated}} _ = pp().bar // expected-error{{value of type '(any P).Type' is a protocol; it cannot be instantiated}} _ = pp().bar(2) // expected-error{{value of type '(any P).Type' is a protocol; it cannot be instantiated}} _ = pp.init() // expected-error{{type 'any P' cannot be instantiated}} _ = pp.init().bar // expected-error{{type 'any P' cannot be instantiated}} _ = pp.init().bar(3) // expected-error{{type 'any P' cannot be instantiated}} _ = P() // expected-error{{type 'any P' cannot be instantiated}} _ = P().bar // expected-error{{type 'any P' cannot be instantiated}} _ = P().bar(4) // expected-error{{type 'any P' cannot be instantiated}} // Instance member of metatype let _: (P) -> (Int) -> () = P.bar let _: (Int) -> () = P.bar(ppp) P.bar(ppp)(5) // Instance member of metatype value let _: (P) -> (Int) -> () = pp.bar let _: (Int) -> () = pp.bar(ppp) pp.bar(ppp)(5) // Static member of existential metatype value let _: () -> () = p.tum // Instance member of existential metatype -- not allowed _ = p.bar // expected-error{{instance member 'bar' cannot be used on type 'P'}} _ = p.mut // expected-error{{instance member 'mut' cannot be used on type 'P'}} // expected-error@-1 {{cannot reference 'mutating' method as function value}} // Static member of metatype -- not allowed _ = pp.tum // expected-error{{static member 'tum' cannot be used on protocol metatype '(any P).Type'}} _ = P.tum // expected-error{{static member 'tum' cannot be used on protocol metatype '(any P).Type'}} // Access typealias through protocol and existential metatypes _ = pp.E.self _ = p.E.self _ = pp.F.self _ = p.F.self // Make sure that we open generics let _: [Int].Type = p.G.self } protocol StaticP { static func foo(a: Int) } extension StaticP { func bar() { _ = StaticP.foo(a:) // expected-error{{static member 'foo(a:)' cannot be used on protocol metatype '(any StaticP).Type'}} {{9-16=Self}} func nested() { _ = StaticP.foo(a:) // expected-error{{static member 'foo(a:)' cannot be used on protocol metatype '(any StaticP).Type'}} {{11-18=Self}} } } } func existentialClassP(_ p: ClassP) { // Instance member of existential) let _: (Int) -> () = id(p.bas) let _: () = id(p.bas(0)) // Instance member of existential metatype) let _: (ClassP) -> (Int) -> () = id(ClassP.bas) let _: (Int) -> () = id(ClassP.bas(p)) let _: () = id(ClassP.bas(p)(1)) } // Partial application of curried protocol methods protocol Scalar {} protocol Vector { func scale(_ c: Scalar) -> Self } protocol Functional { func apply(_ v: Vector) -> Scalar } protocol Coalgebra { func coproduct(_ f: Functional) -> (_ v1: Vector, _ v2: Vector) -> Scalar } // Make sure existential is closed early when we partially apply func wrap(_ t: T) -> T { return t } func exercise(_ c: Coalgebra, f: Functional, v: Vector) { let _: (Vector, Vector) -> Scalar = wrap(c.coproduct(f)) let _: (Scalar) -> Vector = v.scale } // Make sure existential isn't closed too late protocol Copyable { func copy() -> Self } func copyTwice(_ c: Copyable) -> Copyable { return c.copy().copy() } //===----------------------------------------------------------------------===// // Dynamic self //===----------------------------------------------------------------------===// protocol Clonable { func maybeClone() -> Self? func doubleMaybeClone() -> Self?? func subdivideClone() -> (Self, Self) func metatypeOfClone() -> Self.Type func goodClonerFn() -> (() -> Self) } extension Clonable { func badClonerFn() -> ((Self) -> Self) { } func veryBadClonerFn() -> ((inout Self) -> ()) { } func extClone() -> Self { } func extMaybeClone(_ b: Bool) -> Self? { } func extProbablyClone(_ b: Bool) -> Self! { } static func returnSelfStatic() -> Self { } static func returnSelfOptionalStatic(_ b: Bool) -> Self? { } static func returnSelfIUOStatic(_ b: Bool) -> Self! { } } func testClonableArchetype(_ t: T) { // Instance member of extension returning Self) let _: (T) -> () -> T = id(T.extClone) let _: () -> T = id(T.extClone(t)) let _: T = id(T.extClone(t)()) let _: () -> T = id(t.extClone) let _: T = id(t.extClone()) let _: (T) -> (Bool) -> T? = id(T.extMaybeClone) let _: (Bool) -> T? = id(T.extMaybeClone(t)) let _: T? = id(T.extMaybeClone(t)(false)) let _: (Bool) -> T? = id(t.extMaybeClone) let _: T? = id(t.extMaybeClone(true)) let _: (T) -> (Bool) -> T? = id(T.extProbablyClone as (T) -> (Bool) -> T?) let _: (Bool) -> T? = id(T.extProbablyClone(t) as (Bool) -> T?) let _: T! = id(T.extProbablyClone(t)(true)) let _: (Bool) -> T? = id(t.extProbablyClone as (Bool) -> T?) let _: T! = id(t.extProbablyClone(true)) // Static member of extension returning Self) let _: () -> T = id(T.returnSelfStatic) let _: T = id(T.returnSelfStatic()) let _: (Bool) -> T? = id(T.returnSelfOptionalStatic) let _: T? = id(T.returnSelfOptionalStatic(false)) let _: (Bool) -> T? = id(T.returnSelfIUOStatic as (Bool) -> T?) let _: T! = id(T.returnSelfIUOStatic(true)) } func testClonableExistential(_ v: Clonable, _ vv: Clonable.Type) { let _: Clonable? = v.maybeClone() let _: Clonable?? = v.doubleMaybeClone() let _: (Clonable, Clonable) = v.subdivideClone() let _: Clonable.Type = v.metatypeOfClone() let _: () -> Clonable = v.goodClonerFn() // Instance member of extension returning Self let _: () -> Clonable = id(v.extClone) let _: Clonable = id(v.extClone()) let _: Clonable? = id(v.extMaybeClone(true)) let _: Clonable! = id(v.extProbablyClone(true)) // Static member of extension returning Self) let _: () -> Clonable = id(vv.returnSelfStatic) let _: Clonable = id(vv.returnSelfStatic()) let _: (Bool) -> Clonable? = id(vv.returnSelfOptionalStatic) let _: Clonable? = id(vv.returnSelfOptionalStatic(false)) let _: (Bool) -> Clonable? = id(vv.returnSelfIUOStatic as (Bool) -> Clonable?) let _: Clonable! = id(vv.returnSelfIUOStatic(true)) let _ = v.badClonerFn() // expected-error {{member 'badClonerFn' cannot be used on value of type 'any Clonable'; consider using a generic constraint instead}} let _ = v.veryBadClonerFn() // expected-error {{member 'veryBadClonerFn' cannot be used on value of type 'any Clonable'; consider using a generic constraint instead}} } // rdar://problem/50099849 protocol Trivial { associatedtype T } func rdar_50099849() { struct A : Trivial { typealias T = A } struct B : Trivial { // expected-note {{'C' declared as parameter to type 'B'}} typealias T = C.T } struct C : Trivial where W.T == Z.T { typealias T = W.T } let _ = C() // expected-error {{generic parameter 'C' could not be inferred}} // expected-note@-1 {{explicitly specify the generic arguments to fix this issue}} {{17-17=<<#C: Trivial#>>}} } // rdar://problem/50512161 - improve diagnostic when generic parameter cannot be deduced func rdar_50512161() { struct Item {} struct TrivialItem : Trivial { typealias T = Item? } func foo(_: I.Type = I.self, item: I.T) where I : Trivial { // expected-note {{in call to function 'foo(_:item:)'}} fatalError() } func bar(_ item: Item) { foo(item: item) // expected-error {{generic parameter 'I' could not be inferred}} } } // https://github.com/apple/swift/issues/54017 // Compiler crash on missing conformance for default param do { func foo(_ x: T = .init()) -> T { x } // expected-note {{where 'T' = 'String'}} let _: String = foo() // expected-error@-1 {{local function 'foo' requires that 'String' conform to 'Initable'}} } // rdar://70814576 -- failed to produce a diagnostic when implicit value-to-optional conversion is involved. func rdar70814576() { struct S {} func test(_: Fooable?) { } test(S()) // expected-error {{argument type 'S' does not conform to expected type 'Fooable'}} } extension Optional : Trivial { typealias T = Wrapped } extension UnsafePointer : Trivial { typealias T = Int } extension AnyHashable : Trivial { typealias T = Int } extension UnsafeRawPointer : Trivial { typealias T = Int } extension UnsafeMutableRawPointer : Trivial { typealias T = Int } func test_inference_through_implicit_conversion() { struct C : Hashable {} func test(_: T) -> T {} var arr: [C] = [] let ptr: UnsafeMutablePointer = UnsafeMutablePointer(bitPattern: 0)! let rawPtr: UnsafeMutableRawPointer = UnsafeMutableRawPointer(bitPattern: 0)! let _: C? = test(C()) // Ok -> argument is implicitly promoted into an optional let _: UnsafePointer = test([C()]) // Ok - argument is implicitly converted to a pointer let _: UnsafeRawPointer = test([C()]) // Ok - argument is implicitly converted to a raw pointer let _: UnsafeMutableRawPointer = test(&arr) // Ok - inout Array -> UnsafeMutableRawPointer let _: UnsafePointer = test(ptr) // Ok - UnsafeMutablePointer -> UnsafePointer let _: UnsafeRawPointer = test(ptr) // Ok - UnsafeMutablePointer -> UnsafeRawPointer let _: UnsafeRawPointer = test(rawPtr) // Ok - UnsafeMutableRawPointer -> UnsafeRawPointer let _: UnsafeMutableRawPointer = test(ptr) // Ok - UnsafeMutablePointer -> UnsafeMutableRawPointer let _: AnyHashable = test(C()) // Ok - argument is implicitly converted to `AnyHashable` because it's Hashable } // Make sure that conformances transitively checked through implicit conversions work with conditional requirements protocol TestCond {} extension Optional : TestCond where Wrapped == Int? {} func simple(_ x: T) -> T { x } func overloaded(_ x: T) -> T { x } func overloaded(_ x: String) -> T { fatalError() } func overloaded_result() -> Int { 42 } func overloaded_result() -> String { "" } func test_arg_conformance_with_conditional_reqs(i: Int) { let _: Int?? = simple(i) let _: Int?? = overloaded(i) let _: Int?? = simple(overloaded_result()) let _: Int?? = overloaded(overloaded_result()) } // rdar://77570994 - regression in type unification for literal collections protocol Elt { } extension Int : Elt {} extension Int64 : Elt {} extension Dictionary : Elt where Key == String, Value: Elt {} struct Object {} extension Object : ExpressibleByDictionaryLiteral { init(dictionaryLiteral elements: (String, Elt)...) { } } enum E { case test(cond: Bool, v: Int64) var test_prop: Object { switch self { case let .test(cond, v): return ["obj": ["a": v, "b": cond ? 0 : 42]] // Ok } } } // https://github.com/apple/swift/issues/58231 protocol P_58231 {} struct S_58231 {} func f1_58231(x: Int) -> P_58231 { return S_58231() // expected-error{{return expression of type 'S_58231' does not conform to 'P_58231'}} } func f2_58231(x: Int) -> P_58231? { return S_58231() // expected-error{{return expression of type 'S_58231' does not conform to 'P_58231'}} } // https://github.com/apple/swift/issues/61517 protocol P_61517 { init() init(_: Bool) } _ = P_61517() // expected-error{{type 'any P_61517' cannot be instantiated}} _ = P_61517(false) // expected-error{{type 'any P_61517' cannot be instantiated}} _ = P_61517.init() // expected-error{{type 'any P_61517' cannot be instantiated}} _ = P_61517.init(false) // expected-error{{type 'any P_61517' cannot be instantiated}} @_marker protocol Marker {} do { class C : Fooable, Error { func foo() {} } struct Other {} func overloaded() -> C & Marker { fatalError() } func overloaded() -> Other { fatalError() } func isFooable(_: T) {} isFooable(overloaded()) // Ok func isError(_: T) {} isError(overloaded()) // Ok func isFooableError(_: T) {} isFooableError(overloaded()) // Ok } do { func takesFooables(_: [any Fooable]) {} func test(v: String) { takesFooables([v]) // expected-error {{cannot convert value of type 'String' to expected element type 'any Fooable'}} } }