I don't know if this is intended or would be considered a bug, but here is what I think is happening.

In def foo: Option[Wrapper[String]] = Some("foo") the compiler will set the expected type of the argument provided to Some( ) as Wrapper[String]. Then it sees that you provided a String which it is not what is expected, so it looks for an implicit conversion String => Wrapper[String], can't find one, and fails.

Why does it need that expected type stuff, and doesn't just type Some("foo") as Some[String] and afterwards try to find a conversion? Because scalac wants to be able to typecheck the following code:

case class Invariant[T](t: T)
val a: Invariant[Any] = Invariant("s")

In order for this code to work, the compiler can't just type Invariant("s") as Invariant[String] because then compilation will fail as Invariant[String] is not a subtype of Invariant[Any]. The compiler needs to set the expected type of "s" to Any so that it can see that "s" is an instance of Any before it's too late.

In order for both this code and your code to work out correctly, I think the compiler would need some kind of backtracking logic which it doesn't seem to have, perhaps for good reasons.

The reason that your Working code does work, is that this kind of type inference does not span multiple lines. Analogously val a: Invariant[Any] = {val why = Invariant("s"); why} does not compile.

Related Query

More Query from same tag