Why doesn't type inference work here?
scala, structural-typing, type-bounds
Solution
This isn't a Scala compiler bug, but it's certainly a limitation of Scala's type inference. The compiler wants to determine the bound on `X`, `S[T]`, before solving for `X`, but the bound mentions the so far unconstrained type variable `T` which it therefore fixes at `Nothing` and proceeds from there. It doesn't revisit `T` once `X` has been fully resolved ... currently type inference always proceeds from left to right in this sort of case.
If your example accurately represents your real situation then there is a simple fix,
def apply[T](x : S[T]) = x.doSomething
Here `T` will be inferred such that `Minimal` conforms to `S[T]` directly rather than via an intermediary bounded type variable.
Update
Joshua's solution also avoids the problem of inferring type `T`, but in a completely different way.
def apply[T, X <% S[T]](x : X) = x.doSomething
desugars to,
def apply[T, X](x : X)(implicit conv : X => S[T]) = x.doSomething
The type variables `T` and `X` can now be solved for independently (because `T` is no longer mentioned in `X`'s bound). This means that `X` is inferred as `Minimal` immediately, and `T` is solved for as a part of the implicit search for a value of type `X => S[T]` to satisfy the implicit argument `conv`. `conforms` in `scala.Predef` manufactures values of this form, and in context will guarantee that given an argument of type `Minimal`, `T` will be inferred as Int. You could view this as an instance of functional dependencies at work in Scala.
Problem
This problem arose in a module I'm writing, but I have made a minimal case that exhibits the same behaviour. ``` class Minimal[T](x : T) { def doSomething = x } object Sugar { type S[T] = { def doSomething : T } def apply[T, X <: S[T]] (x: X) = x.doSomething } object Error { val a = new Minimal(4) Sugar(a) // error: inferred [Nothing, Minimal[Int]] does not fit the bounds of apply Sugar[Int, Minimal[Int]](a) // works as expected } ``` The problem is that the compiler manages to figure out the inner parameter for `Minimal` (`Int`), but then sets the other occurrence of `T` to `Nothing`, which obviously does not match `apply`. These are definitely the same `T`, as removing the first parameter makes the second complain that T is not defined. Is there some ambiguity that means that the compiler cannot infer the first parameter, or is this a bug? Can I work around this gracefully? Further information: This code is a simple example of an attempt at syntactic sugar. The original code tries to make `|(a)|` mean the modulus of `a`, where a is a vector. Clearly `|(a)|` is better than writing `|[Float,Vector3[Float]](a)|`, but unfortunately I can't use `unary_|` to make this easier. The actual error: inferred type arguments [Nothing,Minimal[Int]] do not conform to method apply's type parameter bounds [T,X <: Sugar.S[T]]