Extension method isn't resolved but can be called directly
Opened this issue · 2 comments
Compiler version
3.3.5 LTS, 3.6.3
Minimized code
enum Child:
case Son(name: String)
extension [A](x: A)(using Child <:< A) def boo: Unit = println("")
// extension [A >: Child](x: A) def boo: Unit = println("") // works
boo(Child.Son("bob")) // compiling
(Child.Son("bob")).boo // not compiling
val x = Child.Son("bob")
x.boo // compilingOutput
Compiler error:
value boo is not a member of Playground.Child.Son
Expectation
According the following rule from the doc about extension methods:
The selection is rewritten to
m[Ts](e)and typechecked, using the following slight modification of the name resolution rules...
I expect that the behavior for direct call and as-field would be the same.
I understand, that there is a difference in type inference: compiler infers type Son in second case. But type Son is very specific, I feel like it shouldn't be inferred for enum:
Generally, the type of a enum case constructor application will be widened to the underlying enum type, unless a more specific type is expected.
Simpler example:
trait TCl[A]
enum Child:
case Son(name: String)
given TCl[Child] = new TCl[Child] {}
extension [A: TCl](x: A) def boo: Unit = println("")
boo(Child.Son("bob"))
Child.Son("bob").boo // doesn't compile
val x = Child.Son("bob")
x.boohttps://scastie.scala-lang.org/road21/a2KV87ICTr29S4zBeBTkbQ/8
Conversely,
extension (x: Child.Son) def boob: Unit = println("boob")
Child.Son("bob").boob
The other rule is "add variance until it typechecks".
trait TCl[-A]