-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add overloading support for case-closures #2015
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
Conversation
case-closures (which are represented as Match nodes) have a known arity just like other function literals. So shape analysis for overloading resolution should apply to them as well.
tests/pos/inferOverloaded.scala
Outdated
// These ones did not work before, still don't work in dotty: | ||
//m.map1 { case (k, v) => k } | ||
//val r = m.map1 { case (k, v) => (k, k*10) } | ||
//val rt: MyMap[Int, Int] = r |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the use case we are interested in for the collections. Do you have an idea why it fails?
Note: The test file in this PR contains 4 cases (lines 32-35) which compile under nsc but not under dotc. This has nothing to do with the current fix. Instead it reveals some pre-existing differences in overloading resolution. From what I could see dotc's results here seem to conform to spec. Essentially, both the
and the
survive shape analysis and therefore a typed argument is needed. Maybe I have overlooked something here? I could not figure out why this passes in nsc. On the other hand, the compiles OK now with dotc after the present PR even if we uncomment the critical definition of |
I believe this works in nsc due to extending scala/scala#5307 to class MySeq[T] {
def map1[U](f: T => U): MySeq[U] = new MySeq[U]
}
class MyMap[A, B] extends MySeq[(A, B)] {
def map1[C, D](f: ((A, B)) => (C, D)): MyMap[C, D] = new MyMap[C, D]
} For
The HOF parameter types of the applicable matches are LUBbed and therefore the |
Actually, I think the strawman will be updated so that the |
Agreed, the instantiations in question are:
Now, according to the SLS the second
In our case the methods have different numbers of type parameters, so they neither match nor override each other. This means we have two members under consideration, not one. So I can't see why we are allowed to "The HOF parameter types of the applicable matches are LUBbed and therefore the Match is typechecked with the expected type ((Int, String)) => ?". |
@odersky The LUBbing is from the spec change here: https://github.com/scala/scala/pull/5307/files#diff-5d74b019862ed901d7800b4ace79fb5b |
@szeiger You nailed it. Yes, that's where the compilers differ. Dotty requires formal parameter types to be the same, whereas scalac forms a lub. |
@szeiger In fact, this was not the problem, after all. The problem was that pre-typing formal parameters of closure arguments did not apply to case-closures. Now it does. This makes |
Right, the argument types are the same, lubbing shouldn't be necessary in this case. I thought |
Classic case of a missed refactoring. There were two ways to look at funargs in overloading resolution, one which checked whether parameters were unspecified and one which didn't. |
@szeiger, could you make sure we didn't miss it as well over at scala/scala? |
@adriaanm Only one change was required for scalac:scala/scala@54bacee#diff-aa951aef1dfedeaa38591c8757a9d13c - This method is called from two places in Typers (checking whether missing parameter types exist and then checking where to apply the computed types) |
case-closures (which are represented as Match nodes) have a known
arity just like other function literals. So shape analysis for
overloading resolution should apply to them as well.
The change is completely analogous to
https://github.com/scala/scala/pull/5698/files
Review by @szeiger?