Solution (source code)

= Solution

The output is \b[`BADDCD`], without a newline. <Method overloading> chooses a signature using <static types>, including the instantiated class <type parameter>; <numeric widening> can make a `Double` parameter applicable to an `Int` argument.

* `a.m(o1)` chooses `m(Int)`, which is more specific than the polymorphic method: `B`.
* `a.m(o2)` uses `m[Double](Double)`: `A`.
* `b.m(o1)` compares `m(Any)` and `m(Double)`. `Int` can widen to `Double`, and `Double` is more specific than `Any`: `D`.
* `b.m(o2)` chooses `m(Double)` over `m(Any)`: `D`.
* `c.m(o1)` compares the instantiated `m(Int)` with `m(Double)` and chooses `m(Int)`: `C`.
* `c.m(o2)` can use only `m(Double)`: `D`.

The third call is the subtle one: the existence of `m(Any)` does not prevent the more specific numeric overload from winning. These are Scala 2 <method overloading> and <numeric widening> rules. <Scala 2.11 expressions specification>[Overloading Resolution and Numeric Widening]{ref}