LYR-SEM0083
an operator with two conformances that fit the operand
An arithmetic operator finds two conformances of the left operand's type to its interface (Mul<int32>, Mul<int16> …) that both take the right operand, with different implementations.
Explanation
a * b calls the mul of the conformance whose argument is b's type. An exact match wins; otherwise a literal adapts to every conformance it fits, and when it fits two that call different functions, nothing in the expression says which is meant. Declaration order is no rule to rely on.
Give the operand the type of the conformance you mean (3 as int32).
Wrong
import std.core { Mul };
struct V {
x: int,
}
extend V :: [Mul<int32>] {
fn mul(rhs: int32): V { return V { x = this.x * (rhs as int) }; }
}
extend V :: [Mul<int16>] {
fn mul(rhs: int16): V { return V { x = this.x * (rhs as int) }; }
}
fn main(): void {
let v = V { x = 2 } * 3;
let _ = v.x;
}
Right
import std.core { Mul };
struct V {
x: int,
}
extend V :: [Mul<int32>] {
fn mul(rhs: int32): V { return V { x = this.x * (rhs as int) }; }
}
extend V :: [Mul<int16>] {
fn mul(rhs: int16): V { return V { x = this.x * (rhs as int) }; }
}
fn main(): void {
let v = V { x = 2 } * (3 as int32);
let _ = v.x;
}