Numeric default fallback VS exclusive trait bound

In the following example I would expect that f32 can be inferred?

trait Scalar { type Out; }
impl Scalar for f32 { type Out = f32; }
// commenting this impl compiles
impl Scalar for f64 { type Out = f64; }

fn op<T: Scalar<Out = f32>>(_: T) {}

fn main() {
    // only `f32` satisfies op's `Out = f32`, `T` should be uniquely inferrable
    op(0.2);
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0271]: type mismatch resolving `<f64 as Scalar>::Out == f32`
  --> src/main.rs:10:8
   |
10 |     op(0.2);
   |     -- ^^^ type mismatch resolving `<f64 as Scalar>::Out == f32`
   |     |
   |     required by a bound introduced by this call
   |
note: expected this to be `f32`
  --> src/main.rs:4:34
   |
 4 | impl Scalar for f64 { type Out = f64; }
   |                                  ^^^
note: required by a bound in `op`
  --> src/main.rs:6:17
   |
 6 | fn op<T: Scalar<Out = f32>>(_: T) {}
   |                 ^^^^^^^^^ required by this bound in `op`

For more information about this error, try `rustc --explain E0271`.
error: could not compile `playground` (bin "playground") due to 1 previous error

Can someone help me understand why the code gets rejected or is this a bug?

Your program seems to belong to this inference category:

As to what exactly constitutes unique determination of the type of a float literal by the program context, I don't know. To be honest, to me (not a compiler engineer) using the associated type of trait bound to determine whether the trait is implemented by either f32 or f64 or both seems a bit far fetched. An easy workaround would be to add a suffix to your literal, like 0.2f32.

Winnowing the trait impl candidates based on the associated type so that the code compiled due to only having one remaining applicable impl would create a semver hazard (a new impl could break the stronger inference).

Even in this case involving float literals, they may one day support f16 and f128, so the set of possible impls may grow.