Scala does overload resolution by taking the methods that could apply and then choosing the most specific among them.
Numeric widening means that (java.lang.Float) and (java.lang.Double) apply to an int arg, but those boxed java types are not promoted, so neither is deemed more specific. They are apples and oranges.
So this works:
scala> val i: java.lang.Float = 3
i: Float = 3.0
but given
scala> def f(x: java.lang.Double) = x
f: (x: Double)Double
scala> f(3.0f)
res5: Double = 3.0
but
scala> f(new java.lang.Float(3.0f))
<console>:12: error: type mismatch;
found : Float
required: Double
f(new java.lang.Float(3.0f))
^
Yet,
scala> object X { def f(i: java.lang.Integer) = 0 ; def f(j: java.lang.Float) = 0 ; def f(k: java.lang.Double) = 0 }
defined object X
then you can pre-promote:
scala> X f (5: java.lang.Integer)
res8: Int = 0