I just got hit by a weird “ambiguous operator” error. It came up with a generic type which does not conform to `Numeric`

, but nonetheless implements all the operators for it. Then, in a conditional extension, I added the conformance. Unfortunately, the operators cannot actually be *used* in the conditional extension, because of an alleged ambiguity.

I’ve cut it down to a small example. In this stripped-down version, there are ways to work around the issue, such as making the conformance unconditional. However in the actual place I encountered it, the conformance must be conditional.

• • •

Let’s start with a simple wrapper type:

```
struct Foo<T: Numeric> : Equatable {
var x: T
}
extension Foo : ExpressibleByIntegerLiteral {
init(integerLiteral value: T.IntegerLiteralType) {
x = T(integerLiteral: value)
}
}
```

Give it some basic operators:

```
extension Foo {
static func += (lhs: inout Foo, rhs: Foo) { lhs.x += rhs.x }
static func -= (lhs: inout Foo, rhs: Foo) { lhs.x -= rhs.x }
static func *= (lhs: inout Foo, rhs: Foo) { lhs.x *= rhs.x }
static func + (lhs: Foo, rhs: Foo) -> Foo {
var result = lhs
result += rhs
return result
}
static func - (lhs: Foo, rhs: Foo) -> Foo {
var result = lhs
result -= rhs
return result
}
static func * (lhs: Foo, rhs: Foo) -> Foo {
var result = lhs
result *= rhs
return result
}
}
```

And add a conditional conformance to `Numeric`

:

```
extension Foo : Numeric where T : FloatingPoint {
typealias Magnitude = T.Magnitude
var magnitude: T.Magnitude { return x.magnitude }
init?<U: BinaryInteger>(exactly n: U) {
guard let x = T(exactly: n) else { return nil }
self.x = x
}
}
```

So far so good.

Now let’s try to use that conformance:

```
extension Foo where T : FloatingPoint {
func foo() {
_ = self + self
}
}
```

…and we’re hit by an error: “ambiguous use of operator `+`

”.

Interestingly, if we move all the operators down into the extension that declares `Numeric`

conformance, then it compiles fine. But with unconditionally-available operators, we get a compiler error.

Is this a known bug?

• • •

The actual place this arose was when trying to implement `Complex<T: SignedNumeric>`

, which cannot conform unconditionally to `SignedNumeric`

because the `magnitude`

requirement doesn’t work when `T`

is an integer type.

So I implemented the arithmetic operators on `Complex`

, but could only provide `SignedNumeric`

conformance when `T: FloatingPoint`

. Unfortunately, that made all the basic operators “ambiguous”.