Dotty: Inference fails for summon with incorrect overlapping instances

Created on 5 Jun 2020  路  7Comments  路  Source: lampepfl/dotty

Minimized code

trait ToResponseCode[A]:
  def toResponseCode: Boolean

given ToResponseCode[Int]:
  def toResponseCode = false

trait ToJSON[A]:
  def encode(a: A): String

given ToJSON[Boolean]:
  def encode(a: Boolean) = a.toString

val responseCode: ToResponseCode[Int] =
  summon

Output

scala[error] 14 | summon [error] | ^ [error] |ambiguous implicit arguments: both object given_ToResponseCode_Int and method given_ToJSON_Boolean match type T of parameter x of method summon in object DottyPredef

Expectation

Should be able to assign the type in summon without it being explicitly annotated.

typer bug

All 7 comments

Replacing summon by implicitly or by summon[ToResponseCode[CREATED[JSON, Int]]] works. This example can probably be minimized further.

I minimized it further 鈽濓笍

can do this too:

given as Int = 0
given as Boolean = true

val r: Int = summon

That looks a lot more minimized 馃槀

It's the price we pay to have summon defined like this:

inline def summon[T](using x: T): x.type = x

Upside: summon can refine the expected type, just like the the in Shapeless does.

Downside: We can't constrain using the expected type, so summon has to come with a type parameter.

I think the price is worth paying. If one does not want it, one can use implicitly. or a home-brewed alternative:

inline def implicitly[T](using x: T): T = x

Cool, any reason not to have implicitly be an inline def moving forward?

Theoretically it may be possibly constrain T, given that we know that T >: x.type <: Int, and we don't know x.type, therefore T <: Int?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

odersky picture odersky  路  126Comments

odersky picture odersky  路  27Comments

odersky picture odersky  路  28Comments

neko-kai picture neko-kai  路  39Comments

sstucki picture sstucki  路  30Comments