I noticed the following in the generated interface for Set's contains in the Standard Library:
extension Set : Sequence where Element : Hashable {
/// Returns an iterator over the members of the set.
public func makeIterator() -> SetIterator<Element>
/// Returns a Boolean value that indicates whether the given element exists
/// in the set.
///
/// This example uses the `contains(_:)` method to test whether an integer is
/// a member of a set of prime numbers.
///
/// let primes: Set = [2, 3, 5, 7]
/// let x = 5
/// if primes.contains(x) {
/// print("\(x) is prime!")
/// } else {
/// print("\(x). Not prime.")
/// }
/// // Prints "5 is prime!"
///
/// - Parameter member: An element to look for in the set.
/// - Returns: `true` if `member` exists in the set; otherwise, `false`.
///
/// - Complexity: O(1)
public func contains(_ member: Set.Element) -> Bool
}
I'd like to understand why it's declared as a conditional conformance.
(I mean, a Set is always a Sequence and Set.Element is always Hashable anyway, so why this conditional conformance?)
Set is first declared only with a Hashable constraint on its generic parameter. In conforms to everything else (including SetAlgebra, Collection, ExpressibleByArrayLiteral, etc) in extensions.
Concerning the Sequence part, I believe this is a way of conforming to a complex protocol hierarchy – You first conform to P, then, in a separate extension, you conform to P1: P and so on:
Set first conforms to Sequence, then to Collection in separate extensions, adding functionality step by step.
Regarding the Hashable part, I understand your concern. It is redundant to constrain the generic parameter to Hashable in every extension for a trivial reason: struct Set<Element> where Element: Hashable
Nevertheless, the compiler doesn't complain about an equivalent example in a playground. IMO, this should produce a redundant constraint warning.
P.S. Xcode 9.2 (Swift 4.0) does show a redundant constraint warning, although accompanied by the error of unsupported conditional conformances.
Interesting! As far as I can tell, this is a bug in SourceKit's rendering of the generated interface. Set's Sequence conformance is declared unconditionally here: swift/Set.swift at main · apple/swift · GitHub