Closed
Description
minimized code
https://scastie.scala-lang.org/60nHfRoiRVONgdxGJpUjZA
opaque type Foo = Int
object Foo
def apply(i: Int): Foo = i
opaque type Bar = Int
object Bar
def apply(i: Int): Bar = i
// ******************************
// Bug example #1, Bar incorrectly acts as subtype of Foo
// when used in a top-level definition.
object FooToString
// Next line gives a compilation error as expected: "Found: Bar => String, Required: Foo => String"
//val fooToString: Foo => String = (b: Bar) => "hi from Bar function"
// This line is identical to the previous line, but it's a
// top-level definition that compiles and is used below.
val fooToString: Foo => String = (b: Bar) => "hi from Bar function" // BUG
// ******************************
// Bug example #2, same as #1 but demonstrated using
// a typeclass instance top-level definition.
trait Show[A]
def show(a: A): String
object Show
// Next line gives a compilation error as expected: "Found: Bar => String, Required: Show[Foo]"
//given Show[Foo] = (f: Bar) => "hi from Show[Foo]"
// This line is identical to the previous line, but it compiles,
// creating an instance of Show[Foo] that's used below.
given Show[Foo] = (f: Bar) => "hi from Show[Foo]" // BUG
def show[A: Show](a: A): String = summon[Show[A]].show(a)
object Main extends App
println(show(Foo(5)))
println(fooToString(Foo(17)))
expectation
As shown in the Scastie snippet, this definition
val fooToString: Foo => String = (b: Bar) => "hi from Bar function"
Is expected to fail compilation with the error Found: Bar => String, Required: Foo => String
but instead compilation succeeds if the definition is top-level.