Should implicit scope access the underlying type of an opaque?

The following code compiles:

opaque type Foo = Int
object Foo:
  given Foo = 1
  val f = summon[Int]

While I understand that within an opaque type companion object the underlying type and the opaque are equivalent, I think this should not be the case for implicit scope. This can lead to strange unplanned ambiguities (happened to me) within the companion.


I don’t really see what kind of ambuiguity can happen here. Can you provide an example of the ambibuity you encountered ?

Well my ambiguity looked something like this:

trait Bar
object Bar:
  given Foo[Bar] = ???

trait Baz
object Baz:
  given Foo[Baz] = ???

opaque type Foo[T] = Int
object Foo:
  export Baz.given
  export Bar.given
  val b = summon[Foo[Baz]] //ambuity error

Now here the error may appear obvious, but consider that Foo, Bar, and Baz were in separate files. It took me a long time to figure out where the ambiguity comes from (although, I must admit, that I was more skeptic of the compiler than myself, due to several bugs I already found. So maybe if I thought of it more without bias I could have figured it out sooner).

Correct me if I’m wrong but if you define your given in another file, it should’nt know the underlying type of the opaque type. If it is not the case I agree it shouldnt.

Nope, it’s not that case. The “transparency” of the underlying opaque type occurs at the file the opaque is defined in no matter what, so even though the given is opaque in another file, it is still “transparent” at the opaque definition.

I mean if the given Foo is defined in another file than the opaque type Foo, it shouldn’t know the underlying type of Foo

That’s not the spec, AFAIK, and indeed the implementation aligns with the spec.