// RUN: %target-parse-verify-swift //===----------------------------------------------------------------------===// // Deduction of generic arguments //===----------------------------------------------------------------------===// func identity(value: T) -> T { return value } func identity2(value: T) -> T { return value } func identity2(value: T) -> Int { return 0 } struct X { } struct Y { } func useIdentity(x: Int, y: Float, i32: Int32) { var x2 = identity(x) var y2 = identity(y) // Deduction that involves the result type x2 = identity(17) var i32_2 : Int32 = identity(17) // Deduction where the result type and input type can get different results var xx : X, yy : Y xx = identity(yy) // expected-error{{cannot convert value of type 'Y' to expected argument type 'X'}} xx = identity2(yy) // expected-error{{cannot convert value of type 'Y' to expected argument type 'X'}} } // FIXME: Crummy diagnostic! func twoIdentical(x: T, _ y: T) -> T {} func useTwoIdentical(xi: Int, yi: Float) { var x = xi, y = yi x = twoIdentical(x, x) y = twoIdentical(y, y) x = twoIdentical(x, 1) x = twoIdentical(1, x) y = twoIdentical(1.0, y) y = twoIdentical(y, 1.0) twoIdentical(x, y) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}} } func mySwap(x: inout T, _ y: inout T) { let tmp = x x = y y = tmp } func useSwap(xi: Int, yi: Float) { var x = xi, y = yi mySwap(&x, &x) mySwap(&y, &y) mySwap(x, x) // expected-error {{passing value of type 'Int' to an inout parameter requires explicit '&'}} {{10-10=&}} // expected-error @-1 {{passing value of type 'Int' to an inout parameter requires explicit '&'}} {{13-13=&}} mySwap(&x, &y) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}} } func takeTuples(_: (T, U), _: (U, T)) { } func useTuples(x: Int, y: Float, z: (Float, Int)) { takeTuples((x, y), (y, x)) takeTuples((x, y), (x, y)) // expected-error{{cannot convert value of type 'Int' to expected argument type 'Float'}} // FIXME: Use 'z', which requires us to fix our tuple-conversion // representation. } func acceptFunction(f: (T) -> U, _ t: T, _ u: U) {} func passFunction(f: (Int) -> Float, x: Int, y: Float) { acceptFunction(f, x, y) acceptFunction(f, y, y) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}} } func returnTuple(_: T) -> (T, U) { } // expected-note {{in call to function 'returnTuple'}} func testReturnTuple(x: Int, y: Float) { returnTuple(x) // expected-error{{generic parameter 'T' could not be inferred}} var _ : (Int, Float) = returnTuple(x) var _ : (Float, Float) = returnTuple(y) // QoI: Propagate contextual information in a call to operands var _ : (Int, Float) = returnTuple(y) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}} } func confusingArgAndParam(f: (T) -> U, _ g: (U) -> T) { confusingArgAndParam(g, f) confusingArgAndParam(f, g) } func acceptUnaryFn(f: (T) -> U) { } func acceptUnaryFnSame(f: (T) -> T) { } func acceptUnaryFnRef(f: inout (T) -> U) { } func acceptUnaryFnSameRef(f: inout (T) -> T) { } func unaryFnIntInt(_: Int) -> Int {} func unaryFnOvl(_: Int) -> Int {} // expected-note{{found this candidate}} func unaryFnOvl(_: Float) -> Int {} // expected-note{{found this candidate}} // Variable forms of the above functions var unaryFnIntIntVar : (Int) -> Int = unaryFnIntInt func passOverloadSet() { // Passing a non-generic function to a generic function acceptUnaryFn(unaryFnIntInt) acceptUnaryFnSame(unaryFnIntInt) // Passing an overloaded function set to a generic function // FIXME: Yet more terrible diagnostics. acceptUnaryFn(unaryFnOvl) // expected-error{{ambiguous use of 'unaryFnOvl'}} acceptUnaryFnSame(unaryFnOvl) // Passing a variable of function type to a generic function acceptUnaryFn(unaryFnIntIntVar) acceptUnaryFnSame(unaryFnIntIntVar) // Passing a variable of function type to a generic function to an inout parameter acceptUnaryFnRef(&unaryFnIntIntVar) acceptUnaryFnSameRef(&unaryFnIntIntVar) acceptUnaryFnRef(unaryFnIntIntVar) // expected-error{{passing value of type '(Int) -> Int' to an inout parameter requires explicit '&'}} {{20-20=&}} } func acceptFnFloatFloat(f: (Float) -> Float) {} func acceptFnDoubleDouble(f: (Double) -> Double) {} func passGeneric() { acceptFnFloatFloat(identity) acceptFnFloatFloat(identity2) } //===----------------------------------------------------------------------===// // Simple deduction for generic member functions //===----------------------------------------------------------------------===// struct SomeType { func identity(x: T) -> T { return x } func identity2(x: T) -> T { return x } // expected-note 2{{found this candidate}} func identity2(x: T) -> Float { } // expected-note 2{{found this candidate}} func returnAs() -> T {} } func testMemberDeduction(sti: SomeType, ii: Int, fi: Float) { var st = sti, i = ii, f = fi i = st.identity(i) f = st.identity(f) i = st.identity2(i) f = st.identity2(f) // expected-error{{ambiguous use of 'identity2'}} i = st.returnAs() f = st.returnAs() acceptFnFloatFloat(st.identity) acceptFnFloatFloat(st.identity2) // expected-error{{ambiguous use of 'identity2'}} acceptFnDoubleDouble(st.identity2) } struct StaticFuncs { static func chameleon() -> T {} func chameleon2() -> T {} } struct StaticFuncsGeneric { // FIXME: Nested generics are very broken // static func chameleon() -> T {} } func chameleon() -> T {} func testStatic(sf: StaticFuncs, sfi: StaticFuncsGeneric) { var x: Int16 x = StaticFuncs.chameleon() x = sf.chameleon2() // FIXME: Nested generics are very broken // x = sfi.chameleon() // typealias SFI = StaticFuncsGeneric // x = SFI.chameleon() _ = x } //===----------------------------------------------------------------------===// // Deduction checking for constraints //===----------------------------------------------------------------------===// protocol IsBefore { func isBefore(other: Self) -> Bool } func min2(x: T, _ y: T) -> T { if y.isBefore(x) { return y } return x } extension Int : IsBefore { func isBefore(other: Int) -> Bool { return self < other } } func callMin(x: Int, y: Int, a: Float, b: Float) { min2(x, y) min2(a, b) // expected-error{{argument type 'Float' does not conform to expected type 'IsBefore'}} } func rangeOfIsBefore< R : IteratorProtocol where R.Element : IsBefore >(range: R) { } func callRangeOfIsBefore(ia: [Int], da: [Double]) { rangeOfIsBefore(ia.makeIterator()) rangeOfIsBefore(da.makeIterator()) // expected-error{{ambiguous reference to member 'makeIterator()'}} } //===----------------------------------------------------------------------===// // Deduction for member operators //===----------------------------------------------------------------------===// protocol Addable { func +(x: Self, y: Self) -> Self } func addAddables(x: T, y: T, u: U) -> T { u + u // expected-error{{binary operator '+' cannot be applied to two 'U' operands}} // expected-note @-1 {{overloads for '+' exist with these partially matching parameter lists: }} return x+y } //===----------------------------------------------------------------------===// // Deduction for bound generic types //===----------------------------------------------------------------------===// struct MyVector { func size() -> Int {} } func getVectorSize(v: MyVector) -> Int { return v.size() } func ovlVector(v: MyVector) -> X {} func ovlVector(v: MyVector>) -> Y {} func testGetVectorSize(vi: MyVector, vf: MyVector) { var i : Int i = getVectorSize(vi) i = getVectorSize(vf) getVectorSize(i) // expected-error{{cannot convert value of type 'Int' to expected argument type 'MyVector<_>'}} var x : X, y : Y x = ovlVector(vi) x = ovlVector(vf) var vvi : MyVector> y = ovlVector(vvi) var yy = ovlVector(vvi) yy = y y = yy } // postfix operator <*> {} protocol MetaFunction { associatedtype Result postfix func <*> (_: Self) -> Result? } protocol Bool_ {} struct False : Bool_ {} struct True : Bool_ {} postfix func <*> (_: Test) -> Int? { return .none } postfix func <*> (_: Test) -> String? { return .none } class Test : MetaFunction { typealias Result = Int } // picks first <*> typealias Inty = Test.Result var iy : Inty = 5 // okay, because we picked the first <*> var iy2 : Inty = "hello" // expected-error{{cannot convert value of type 'String' to specified type 'Inty' (aka 'Int')}} // rdar://problem/20577950 class DeducePropertyParams { let badSet: Set = ["Hello"] } // SR-69 struct A {} func foo() { for i in min(1,2) { // expected-error{{type 'Int' does not conform to protocol 'Sequence'}} } let j = min(Int(3), Float(2.5)) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}} let k = min(A(), A()) // expected-error{{argument type 'A' does not conform to expected type 'Comparable'}} let oi : Int? = 5 let l = min(3, oi) // expected-error{{value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?}} }