Lyricdev
GitHub

LYR-SEM0092

inference through a type that conforms twice

error · spec 05-interfaces

A generic call infers a type argument from an argument's conformance to an interface, and the argument's type conforms to that interface more than once with different type arguments.

Explanation

When a parameter's type is an interface instance such as Source<T>, T is read from the argument type's conformance. A type conforming as both Source<int> and Source<string> gives two answers, and the order of the conformances must never decide a call.

Write the type argument explicitly: take<int>(…).

Wrong

interface Source<T> {
    fn get(): T;
}

struct Both {
    n: int,
}

extend Both :: [Source<int>] {
    fn get(): int { return this.n; }
}

extend Both :: [Source<string>] {
    fn get(): string { return "n"; }
}

fn take<T>(s: Source<T>): T {
    return s.get();
}

fn main(): void {
    let _ = take(Both { n = 1 });
}
interface Source<T> {
    fn get(): T;
}

struct Both {
    n: int,
}

extend Both :: [Source<int>] {
    fn get(): int { return this.n; }
}

extend Both :: [Source<string>] {
    fn get(): string { return "n"; }
}

fn take<T>(s: Source<T>): T {
    return s.get();
}

fn main(): void {
    let _ = take<int>(Both { n = 1 });
}