Why are where clauses only valid on functions with generic parameters?

Viewed 3336

It seems absurd that this method signature does not compile in Swift 4:

class Bar<ValueType> { 
    func version() throws -> String where ValueType == [String: Any] { ... }
}   

(Error: where clause cannot be attached to a non-generic declaration)
but this compiles fine:

class Bar<ValueType> { 
   func version<T>(_ foo: T? = nil) throws -> String where ValueType == [String: Any] { ... }  
} 

Anyone have insight as to why this is the case?

2 Answers

That has been finally allowed in Swift 5.3. See Contextual Where Clauses in the official Language Guide.

Citing from there:

You can write a generic where clause as part of a declaration that doesn’t have its own generic type constraints, when you’re already working in the context of generic types. For example, you can write a generic where clause on a subscript of a generic type or on a method in an extension to a generic type.

...

extension Container {
    func average() -> Double where Item == Int {
        var sum = 0.0
        for index in 0..<count {
            sum += Double(self[index])
        }
        return sum / Double(count)
    }

That compiles just fine in Xcode 12 beta 4, but won't work in Xcode 11.6 that is shipped with Swift 5.2.4.

Related