Pattern matching regression in Swift 5.3/Xcode 12?

I have an error enum like so:

public enum RequestError: Error, Equatable {
    case httpError(HTTPStatus, data: Data?)
    case networkError(URLError.Code)
    case mappingError(DecodingError)
    // some other cases
}

By defining functions like this:

public extension RequestError {
    static func ~= (pattern: HTTPStatus, value: Self) -> Bool {
        guard case .httpError(pattern, _) = value else { return false }
        return true
    }
}

… I used to be able to do this:

switch error {
case .requestFailed(.unauthorized):  ...
case .requestFailed(.notConnectedToInternet): ...
}

In Xcode 12 this doesn't work anymore.

I can fix the latter of the two cases above by adding the type explicitly, but not the former:

switch error {
// Error: Cannot convert value of type 'RequestError' to specified type 'HTTPStatus'
case .requestFailed(HTTPStatus.unauthorized): ...
// Works!
case .requestFailed(URLError.notConnectedToInternet): ...
}

Apple Swift version 5.3 (swiftlang-1200.0.16.9 clang-1200.0.22.5)

1 Like

Explicitly writing out the deep enum case obviously works, too:

switch error {
case .requestFailed(.httpError(.unauthorized, _)): ...
case .requestFailed(URLError.notConnectedToInternet): ...
}

But that is not as succinct and clear to read as the previous version. And also I wonder why this used to work, but doesn't anymore, and why the URLError.Code case can be fixed, but not the HTTPStatus case.