-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Overloading doesn't work with contextual functions #7790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is actually masking a different error, i.e. you can't define two overloads with a single Function1 argument as they are the same after erasure |
It works without givens. Some functions work while others don't, see #7792. |
Ah ok, different situations produce different results, thanks for pointing out trait Foo
given Int = 10
def map(f: (Int) => Int) = f
def map(f: (Int) => String) = f
@main def Test =
val m: Foo = ???
m.map((given x: Int) => x) ^ by purely removing given in the case above with 0.20.0-RC1 i get -- [E120] Duplicate Symbol Error: test.scala:4:6 -------------------------------
4 | def map(f: (Int) => String) = f
| ^
| Double definition:
| def map(f: Int => Int): Int => Int in trait Foo at line 3 and
| def map(f: Int => String): Int => String in trait Foo at line 4
| have the same type after erasure.
-- Error: test.scala:8:2 -------------------------------------------------------
8 | m.map((given x: Int) => x)
| ^
| cannot merge
| method map in trait Foo of type (f: Int => String): Int => String and
| method map in trait Foo of type (f: Int => Int): Int => Int
| they are both defined in trait Foo but have matching signatures
| (f: Int => String): Int => String and
| (f: Int => Int): Int => Int
| as members of value m
|
two errors found |
If you actually call f at the right hand side of your maps on something, the error should go away. But yeah, interactions of lambdas and overloading look flaky. |
Ah interesting, At the JVM level the return type distinguishes two overloads with the same parameters, but the Java language only distinguishes overloads by the arguments apparently. |
This example is not accepted by java, even though the method signatures are essentially what public interface Bar {
default public int map(java.util.function.Function<Object, Object> f) {
return 0;
}
default public String map(java.util.function.Function<Object, String> f) {
return "";
}
} |
Is there a workaround for this? Not being able to overload higher-order functions is something I run into often. It sometimes takes a while to figure out why they would be equal too, is there a way to see the signatures after erasure? [error] |Double definition:
[error] |def ul: ((org.scalajs.dom.html.UList) ?=> Unit) => (org.scalajs.dom.html.Element
[error] | )
[error] | ?=> org.scalajs.dom.html.UList in package object lib$package at line 60 and
[error] |def ul: (String, String, String, String) => ((org.scalajs.dom.html.UList) ?=>
[error] | Unit
[error] |) => (org.scalajs.dom.html.Element) ?=> org.scalajs.dom.html.UList in package object lib$package at line 61
[error] |have the same type after erasure. |
Updated syntax trait Foo:
given Int = 10
def map(f: Int ?=> Int) = f
def map(f: Int ?=> String) = f
@main def Test =
val m: Foo = ???
m.map((x: Int) ?=> x)
|
Revisiting this, this now seems to compile as expected: //> using scala 3.3.1-RC1-bin-20230510-d6c643c-NIGHTLY
trait Foo:
given Int = 10
def map(f: Int ?=> Int) = f
def map(f: Int ?=> String) = f
@main def Test =
val m: Foo = ???
m.map((x: Int) ?=> x) I'll go ahead and close, but please do report back if I'm misunderstanding something and this shouldn't be closed. |
minimized code
Says:
expectation
Clearly the alternative
(f: (Int) ?=> Int): Int
should match the argument(Int) ?=> Int
.The text was updated successfully, but these errors were encountered: