You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Infer generics bounded from above through another generic #285
Inference only follows a relation between two generics in one direction, so a generic that's only bounded from above through another generic can't be inferred:
fn feed<A, B>(f: fn(a: A) -> B, g: fn(b: B) -> Int) -> fn(a: A) -> Int {
fn(a: A) => g(f(a))
}
fn identity<U>(x: U) -> U {
x
}
fn inc(x: Int) -> Int {
x + 1
}
fn main() -> Int {
let h = feed(identity, inc);
h(1)
}
Error: Cannot infer generic `A` for `feed`; specify it explicitly, e.g. `feed::<...>()` at 14:13
Error: Cannot assign `fn(x: Int) -> Int` to `fn(b: A) -> Int`, since they are incompatible at 14:28
identity gives A ≤ B, and inc gives B ≤ Int, so A = B = Int is a valid instantiation. Reproduces on main (bf81a085) and on #265's branch (675320f4).
Proposal
#265 resolves a generic through the lower candidates of the generics it's bounded below by (A: [B] gives A the lower candidates of B). The reverse, propagating B's upper candidates to a generic that appears in B's lower list, isn't done. Doing it would let A fall back to its upper bound Int when nothing bounds it from below.
A single generic with only an upper bound is already inferred as that bound: fn f<T>(g: fn(x: T) -> Int) -> Int called as f(inc) compiles on main. This would apply the same rule transitively.
Activity