scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.87k stars 1.06k forks source link

IllegalArgumentException when invoking applyDynamic on a Selectable #16984

Open dgruntz opened 1 year ago

dgruntz commented 1 year ago

Compiler version

3.2.0

Minimized code

import scala.reflect.Selectable.reflectiveSelectable
def f : { def foo(as: String*): String } = new {
   def foo(s: String*) = s.toList.mkString
}
f.foo()
f.foo("f", "oo")

Output

scala> f.foo("f", "oo")
java.lang.IllegalArgumentException: wrong number of arguments
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:568)
  at scala.reflect.Selectable.applyDynamic(Selectable.scala:40)
  at scala.reflect.Selectable.applyDynamic$(Selectable.scala:11)
  at scala.reflect.Selectable$DefaultSelectable.applyDynamic(Selectable.scala:51)
  ... 34 elided

Expectation

No exception should be thrown and the result of the two invocations should be the empty string or the string "foo", i.e. the behaviour should be similar as if explicit types were used:

trait FOO { def foo(as: String*): String }
def f : FOO = new {
   def foo(s: String*) = s.toList.mkString
}
f.foo()
f.foo("f", "oo")
prolativ commented 1 year ago

It looks like the problem is because varargs are erased to Seq so there's a mismatch between what the implementation of applyDynamic in reflect.Selectable gets from reflection and what the compiler would expect to be there. Seems related to https://github.com/lampepfl/dotty/issues/16995