blob: 5d2fd6ec620b27ac789a242d1727422e5b642cf1 [file] [log] [blame]
// RUN: %target-run-simple-swift %s
// REQUIRES: executable_test
protocol P {
func f0() -> Int;
func f(x:Int, y:Int) -> Int;
}
protocol Q {
func f(x:Int, y:Int) -> Int;
}
struct S : P, Q, Equatable {
// Test that it's possible to denote a zero-arg requirement
// (This involved extended the parser for unqualified DeclNames)
@_implements(P, f0())
func g0() -> Int {
return 10
}
// Test that it's possible to implement two different protocols with the
// same-named requirements.
@_implements(P, f(x:y:))
func g(x:Int, y:Int) -> Int {
return 5
}
@_implements(Q, f(x:y:))
func h(x:Int, y:Int) -> Int {
return 6
}
// Test that it's possible to denote an operator requirement
// (This involved extended the parser for unqualified DeclNames)
@_implements(Equatable, ==(_:_:))
public static func isEqual(_ lhs: S, _ rhs: S) -> Bool {
return false
}
}
func call_P_f_generic<T:P>(p:T, x: Int, y: Int) -> Int {
return p.f(x:x, y:y)
}
func call_P_f_existential(p:P, x: Int, y: Int) -> Int {
return p.f(x:x, y:y)
}
func call_Q_f_generic<T:Q>(q:T, x: Int, y: Int) -> Int {
return q.f(x:x, y:y)
}
func call_Q_f_existential(q:Q, x: Int, y: Int) -> Int {
return q.f(x:x, y:y)
}
let s = S()
assert(call_P_f_generic(p:s, x:1, y:2) == 5)
assert(call_P_f_existential(p:s, x:1, y:2) == 5)
assert(call_Q_f_generic(q:s, x:1, y:2) == 6)
assert(call_Q_f_existential(q:s, x:1, y:2) == 6)
assert(!(s == s))
// Note: at the moment directly calling the member 'f' on the concrete type 'S'
// doesn't work, because it's considered ambiguous between the 'g' and 'h'
// members (each of which provide an 'f' via the 'P' and 'Q' protocol
// conformances), and adding a non-@_implements member 'f' to S makes it win
// over _both_ the @_implements members. Unclear if this is correct; I think so?
// print(s.f(x:1, y:2))