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
ambiguous overloading due to sam #9871
Comments
Imported From: https://issues.scala-lang.org/browse/SI-9871?orig=1 |
@retronym said: |
Moses Nakamura (mosesn) said: |
@SethTisue said: if you can supply a standalone reproduction, I'd be happy to check it against PR 5307 for you (and add it to our suite of regression tests, too!) another possibility would be for you to wait for 2.12.0-RC1 to come out and then attempt to rebuild all your libs against it. I'm retargeting for 2.12.1 because this isn't a blocker for 2.12.0-RC1 or 2.12.0. but we're definitely interested in working with you to find out if this has been resolved. |
@SethTisue said (edited on Aug 23, 2016 10:14:28 PM UTC): any time you have the abstract class Service extends (Int => String)
(_.toString): Service from compiling. (Noticed first by Lukas, scala/scala#5307 (comment)) Adriaan has a WIP patch at scala/scala#5126 but its future is unclear (in any case, it won't make 2.12.0). making this compile makes other things not compile (since new ambiguities are possible), so it's not clear-cut what to do. |
Moses Nakamura (mosesn) said: |
@SethTisue said (edited on Aug 23, 2016 10:44:31 PM UTC): in other news, scala/scala#5357 attempts to make the code in my last comment compile (without addressing all of 5126), and may make RC1 |
@SethTisue said: |
Moses Nakamura (mosesn) said: |
Moses Nakamura (mosesn) said (edited on Dec 2, 2016 9:35:45 PM UTC): |
@xeno-by said (edited on Dec 3, 2016 12:15:47 AM UTC): abstract class MyFunction1[T, U] extends Function1[T, U]
object Test {
def foo(x: Function1[Int, Int]) = ???
def foo(x: MyFunction1[Int, Int]) = ???
val myf: MyFunction1[Int, Int] = ???
foo(myf)
} 16:14 ~/Projects/2121/sandbox (2.12.x)$ s
Test.scala:8: error: ambiguous reference to overloaded definition,
both method foo in object Test of type (x: MyFunction1[Int,Int])Nothing
and method foo in object Test of type (x: Int => Int)Nothing
match argument types (MyFunction1[Int,Int])
foo(myf)
^ |
Moses Nakamura (mosesn) said: It seems like the problem arises only when it both extends Function1 and it's a SAM. |
@xeno-by said (edited on Dec 3, 2016 1:06:26 AM UTC): In particular, it thinks that: isAsSpecific((x: Int => Int)Nothing, (x: MyFunction1[Int,Int])Nothing) = true In order to check specificity, isAsSpecific calls isCompatible (https://github.com/scala/scala/blob/ccfa36071f0623d64474f37b12d40a838aac1b4e/src/compiler/scala/tools/nsc/typechecker/Infer.scala#L294) passing Int => Int and MyFunction1[Int, Int] as arguments to that method. The isCompatible check succeeds because it falls through into the isCompatibleSam case. It thinks that Int => Int is compatible with MyFunction1[Int, Int]. After isCompatible returns true, isAsSpecific concludes that the overload with Int => Int is as specific as the overload with MyFunction1[Int, Int]. As a result, overload resolution fails with an ambiguity. I think that isCompatible works incorrectly. Not every Int => Int is compatible with MyFunction1[Int, Int]. Only lambdas are compatible with that type. Am I correct in pointing this out, or that was done deliberately? |
@adriaanm said: We pretend all expressions of function type are compatible with the corresponding sam type, even if it's only really true for function literals, as you say. This is to make overloading work for the other variation when |
@adriaanm said: |
@xeno-by said: |
@xeno-by said: |
Moses Nakamura (mosesn) said: |
@adriaanm said: |
I'm experiencing the same issue in Scala 2.13.0-M5. I'm using a Java library called When calling this method using a lambda expression in Scala 2.12, it compiles my lambda to an instance of the BukkitRunnable, so it essentially chooses the wrong overload. In Scala 2.13 however the compiler gives me an error:
javac doesn't have this problem because in Java only functional interfaces can be implemented using lambda expressions, not abstract classes. It would be nice if the scala compiler picked the same overload as the java compiler in such a case. |
We have a class,
Service
which extendsFunction1
, and another method,Filter#andThen
which takes either aService
or aFunction1
as an argument. With the scalac flag-Xexperimental
set, we get "ambiguous overload".Details and reproduction case here:
twitter/scrooge#238
The text was updated successfully, but these errors were encountered: