-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Code not compiling when Unit-returning SAM and overloaded methods involved #13549
Comments
Could you simplify the example to not rely on an external library? It should only require defining the assertThrows overload manually with a |
@smarter Shall I still write the |
OK, I managed to reproduce it using only Scala, @smarter let me know if you'd like more info and/or if the reproducer is good enough. |
I also tried Scala 3.1.0-RC2 and it fails with the same errors |
Thanks, this is great! |
Without overloading, a function literal `() => 3` whose expected type is a Unit-returning SAM gets typed as `() => { 3; () }` as expected, but with overloading we first type the function literal without an expected type and then compare it against the formal parameter type. This commit makes this check succeed by replacing a result type of `Unit` by `WildcardType` so we end up comparing `() => Int <:< () => ?` instead of `() => Int <:< () => Unit`. Fixes scala#13549.
Without overloading, a function literal `() => 3` whose expected type is a Unit-returning SAM gets typed as `() => { 3; () }` as expected, but with overloading we first type the function literal without an expected type and then compare it against the formal parameter type. This commit makes this check succeed by replacing a result type of `Unit` by `WildcardType` so we end up comparing `() => Int <:< () => ?` instead of `() => Int <:< () => Unit`. Fixes scala#13549.
I gave this an attempt in #13584 which also explains what the issue is, but it broke one project in our community build because overloading resolution in one situation became ambiguous. It might be possible to fix this by tweaking overloading resolution some more but our resolution rules are already very complex so I'm hesitant to pile on more things on top. I also discovered that Java never does this adaptation of the result type of a lambda: Assertions.assertThrows(IllegalArgumentException.class, () -> 3); A.java:5: error: no suitable method found for assertThrows(Class<IllegalArgumentException>,()->3)
Assertions.assertThrows(IllegalArgumentException.class, () -> 3);
^
method Assertions.<T#1>assertThrows(Class<T#1>,Executable) is not applicable
(cannot infer type-variable(s) T#1
(argument mismatch; bad return type in lambda expression
int cannot be converted to void))
method Assertions.<T#2>assertThrows(Class<T#2>,Executable,String) is not applicable
(cannot infer type-variable(s) T#2
(actual and formal argument lists differ in length))
method Assertions.<T#3>assertThrows(Class<T#3>,Executable,Supplier<String>) is not applicable
(cannot infer type-variable(s) T#3
(actual and formal argument lists differ in length))
where T#1,T#2,T#3 are type-variables:
T#1 extends Throwable declared in method <T#1>assertThrows(Class<T#1>,Executable)
T#2 extends Throwable declared in method <T#2>assertThrows(Class<T#2>,Executable,String)
T#3 extends Throwable declared in method <T#3>assertThrows(Class<T#3>,Executable,Supplier<String>) To me this is a huge point in favor of staying with the current behavior because having overloading resolution behaves like Java ensures that APIs designed for Java will work the same in Scala, whereas if we stray from that we can easily break them as evidenced by the failure in #13584. Therefore I'm closing this issue as "won't fix", although you're welcome to contest that and keep discussing here or on https://contributors.scala-lang.org/ |
This is a reported bug that unfortunately can't be fixed easily without breakage on Scala's side. For further information check scala/scala3#13549
I think there seems to be a problem with SAM conversions and choosing the right overloaded method. Sorry if the bug already exists I couldn't find one.
Compiler version
Scala 3.0.2 and 3.1.0-RC2
Minimized code
You can find a reproducer here: https://github.com/jlprat/overload-sam-reproducer/
Output
Expectation
Code should compile
The text was updated successfully, but these errors were encountered: