Skip to content

Fix #3945: Fix eta expansion for partially applied methods #3981

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

Merged
merged 4 commits into from
Feb 15, 2018

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Feb 11, 2018

This was a tricky one to fix.

Copy link
Contributor

@biboudis biboudis left a comment

Choose a reason for hiding this comment

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

If I remove the explicit type annotation from int in q I get:

9 |  val p: (String => String) => (String) => (Int) => String = int
  |                                                                ^
  |                    found:    String => Nothing => String => Int => String
  |                    required: String => String => String => Int => String
  |

After tracing the constraint set a bit I see that the constraint A <: String is indeed added. But the type is approximated from below and is instantiated with Nothing. WDYT?

@biboudis biboudis assigned odersky and unassigned biboudis Feb 13, 2018
Take bindingTree into account when deciding which type variables to
instantiate before an implicit search. The additions to i3945.scala
fail without this change.

Also two other tweaks.
@odersky
Copy link
Contributor Author

odersky commented Feb 15, 2018

Test output for failed tests is missing. I just see exit code 1.

@allanrenucci
Copy link
Contributor

Test output for failed tests is missing. I just see exit code 1.

Looking into it

@odersky odersky assigned biboudis and unassigned odersky Feb 15, 2018
Copy link
Contributor

@biboudis biboudis left a comment

Choose a reason for hiding this comment

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

LGTM!

@biboudis biboudis merged commit 36cc65a into scala:master Feb 15, 2018
@allanrenucci allanrenucci deleted the fix-#3945 branch February 15, 2018 14:15
odersky added a commit to dotty-staging/dotty that referenced this pull request Mar 1, 2018
This is an altogether unsatisfying scenario. In scala#4032 there's an unconstrained
type variable that should be interpolated and it's a coin flip whether we instantiate
it to the lower or upper bound. A completely unrelated change in scala#3981 meant that
we instantiated the variable to the upper instead of the lower bound which caused
the program to fail. We now fix it by adding another condition which is also more
or less arbitrary: if neither lower bound nor upper bound is defined, we now prefer
again the lower bound. But all of this is quite arbitrary. The fact is that we do
cut off some parts of the search space in arbitrary ways and programs have come on
rely on the specific arbitrary way in which we do it.
odersky added a commit to dotty-staging/dotty that referenced this pull request Mar 2, 2018
Intrepolation is a pretty delicate scenario. It's difficult to even say what is right and what
is wrong. In scala#4032 there's an unconstrained type variable that should be interpolated and it's a coin
flip whether we instantiate it to the lower or upper bound. A completely unrelated change in
scala#3981 meant that we instantiated the variable to the upper instead of the lower bound which
caused the program to fail. The failure was because the type variable appeared covariantly
in the lower bound of some other type variable. So maximizing the type first type variable
overconstrained the second. We avoid this problem now by computing the variance of the type
variable that's eliminated in the rest of the constraint. We take this into account to
instantiate the variable so that it narrows the overall constraint the least, defaulting
again to lower bound if there is not best direction. Since the test is expensive (linear
in the constraint size), we do this only if the variable's lower bound is unconstrained.
We could do it for all non-occurring type variables, but have to see how that would affect
performance.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants