A curiosity between cases and extension members

(Back from a self-imposed month-long hiatus)

Here's something I found. I started with:

enum UInt0 { case zero }

Then I added some basic numeric conformance:

extension UInt0: AdditiveArithmetic {
    public static func + (lhs: Self, rhs: Self) -> Self { return .zero }
    public static func += (lhs: inout Self, rhs: Self) {}
    public static func - (lhs: Self, rhs: Self) -> Self { return .zero }
    public static func -= (lhs: inout Self, rhs: Self) {}
}

The problem is when I tried adding Numeric conformance. This protocol refines both AdditiveArithmetic and ExpressibleByIntegerLiteral. However, AA has an extension triggered by co-conformance to EBIL that adds a type-static .zero member. The case version does not cancel the member version, and both are given the same priority, so I get an ambiguous-name error. Here, the two versions would have the same type, but I see that wouldn't necessarily be that way in general for contexts outside of Numeric, so it has to post an error here. The workaround is to rename the case.

(This wasn't a problem when these protocols were written because back then an enumeration case could not be used to satisfy a type-level member of a protocol.)

I wonder how this happened. Could this be fixed? Should this be fixed?

4 Likes