Implicit parameters break type inference or inference does not suffice for their resolution?

305 Views Asked by At

Type inference works fine in this example until I add the implicit ordering evidence. Type inference rules (from left to right & across parameter lists) seem to be satisfied, but there is something in regards to the implicit that breaks it.

case class Insert[I, O : Ordering](arg: I)
def execute[I,O](req: Insert[I,O]): O = null.asInstanceOf[O]
val result: Int = execute(Insert("test"))

Error:(5, 39) diverging implicit expansion for type Ordering[O]
starting with method Tuple9 in object Ordering
lazy val result: Int = execute(Insert("test"));}
                                     ^

This compiles and works fine:

case class Insert[I, O](arg: I)
def execute[I,O](req: Insert[I,O]): O = null.asInstanceOf[O]
val result: Int = execute(Insert("test"))

So either type inference isn't sufficient for implicit resolution OR implicit resolution breaks type inference.

I guess the O type is inferred but when implicit resolution is happening, it sees it as Nothing, in other words, it sees it as if I didn't specified Int in val result: Int. Is it a bug?

1

There are 1 best solutions below

7
On BEST ANSWER

The issue here is that scala cannot infer the O type because it is not present in Insert

// I is in the parameter list but there is no O to be found
case class Insert[I, O](arg: I)(implicit evidence: Ordering[O]) 

This leaves the compiler no choice but to infer O to be Nothing. Creating an instance of Insert will then fail to compile.

scala> val i = Insert(3)
<console>:9: error: diverging implicit expansion for type Ordering[O]
starting with method Tuple9 in object Ordering
   val i = Insert(3)

The diverging implicit expansion error is scala attempting to find an implicit that works for this case and getting caught in a cycle. It is a red herring.