Skip to content
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

Overloading resolution: Handle SAM types more like Java and Scala 2 #12097

Merged
merged 3 commits into from
Apr 17, 2021

Conversation

smarter
Copy link
Member

@smarter smarter commented Apr 15, 2021

resolveOverloaded is called twice, first with implicit conversions
off, then on. Before this commit, turning off implicit conversions also
turned off SAM conversions, this behavior does not match Java or Scala 2
which means we could end up picking a different overload than they
do (cf #11938).

This commit enables SAM conversions in the first pass, except for
conversions to PartialFunction as that would break a lot of existing
code and wouldn't match how either Java or Scala 2 pick overloads.

This is an alternative to #11945 (which special-cased
SAM types with an explicit @FunctionalInterfaces annotation) and #11990
(which special-cased SAM types that subtype a scala Function type).
Special-casing PartialFunction instead seems more defensible since it's
already special-cased in Scala 2 and is not considered a SAM type by
Java.

Fixes #11938.

Previously we caught this in Typer, but doing it in the `SAMType`
extractor is more robust because it is used in overloading resolution,
and this will be needed in a subsequent commit of this PR to avoid
selecting the wrong overload in some cases.

This required dropping the final flag from the compiler-generated
ContextFunctionN, instead we explicitly prevent subclasses in RefChecks.
The two pass approach was originally introduced in
295c981 to lower the priority of
implicit conversions, but just a month later in
6253125 a similar two pass approach was
used to call resolveOverloaded which itself calls narrowByTrees,
rendering the first commit moot.

Therefore, we can just remove this first pass and all associated code
without affecting anything.
@smarter smarter added this to the 3.0.0-RC3 milestone Apr 15, 2021
`resolveOverloaded` is called twice, first with implicit conversions
off, then on. Before this commit, turning off implicit conversions also
turned off SAM conversions, this behavior does not match Java or Scala 2
which means we could end up picking a different overload than they
do (cf scala#11938).

This commit enables SAM conversions in the first pass, _except_ for
conversions to PartialFunction as that would break a lot of existing
code and wouldn't match how either Java or Scala 2 pick overloads.

This is an alternative to scala#11945 (which special-cased
SAM types with an explicit `@FunctionalInterfaces` annotation) and scala#11990
(which special-cased SAM types that subtype a scala Function type).
Special-casing PartialFunction instead seems more defensible since it's
already special-cased in Scala 2 and is not considered a SAM type by
Java.

Fixes scala#11938.
@smarter smarter force-pushed the fix-11938-new branch 2 times, most recently from cfafc83 to 6cc5b49 Compare April 15, 2021 13:06
@smarter smarter requested a review from odersky April 15, 2021 14:43
@smarter smarter assigned odersky and unassigned smarter Apr 15, 2021
@smarter smarter added the backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it. label Apr 15, 2021
Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First three commits are good for backporting.

Let's split off the last commit and make that a separate PR.

I am not 100% sure how precise the closure detection in the last commit is. So let's avoid any risk and do exactly like Scala 2 for the RC.

@odersky odersky assigned smarter and unassigned odersky Apr 17, 2021
@smarter
Copy link
Member Author

smarter commented Apr 17, 2021

OK, sounds good to me.

@smarter smarter enabled auto-merge April 17, 2021 15:18
@smarter smarter added backport:accepted This PR needs to be backported, once it's been backported replace this tag by "backport:done" and removed backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it. labels Apr 17, 2021
@smarter smarter disabled auto-merge April 17, 2021 17:25
@smarter smarter merged commit c57aa0a into scala:master Apr 17, 2021
@smarter smarter deleted the fix-11938-new branch April 17, 2021 17:26
@smarter smarter added backport:done This PR was successfully backported. and removed backport:accepted This PR needs to be backported, once it's been backported replace this tag by "backport:done" labels Apr 17, 2021
@Kordyjan Kordyjan modified the milestones: 3.0.0-RC3, 3.0.1 Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:done This PR was successfully backported.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Different overloading rules in Scala 2 and 3 for SAMs
3 participants