Skip to content

Fix #4032: Fix direction of instantiation. #4059

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 1 commit into from
Mar 5, 2018

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Mar 1, 2018

Interpolation is a pretty delicate scenario. It's difficult to even say what is right and what
is wrong. In #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
#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 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.

@odersky odersky requested a review from allanrenucci March 1, 2018 20:10
Copy link
Member

@dottybot dottybot left a comment

Choose a reason for hiding this comment

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

Hello, and thank you for opening this PR! 🎉

All contributors have signed the CLA, thank you! ❤️

Commit Messages

We want to keep history, but for that to actually be useful we have
some rules on how to format our commit messages (relevant xkcd).

Please stick to these guidelines for commit messages:

  1. Separate subject from body with a blank line
  2. When fixing an issue, start your commit message with Fix #<ISSUE-NBR>:
  3. Limit the subject line to 72 characters
  4. Capitalize the subject line
  5. Do not end the subject line with a period
  6. Use the imperative mood in the subject line ("Added" instead of "Add")
  7. Wrap the body at 80 characters
  8. Use the body to explain what and why vs. how

adapted from https://chris.beams.io/posts/git-commit

Have an awesome day! ☀️

@Blaisorblade
Copy link
Contributor

Unclear from the description: Does this fix implement Scalac's behavior or just fixes the specific failure? In the latter case, this fix could cause regressions in other projects, right?

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.
@odersky
Copy link
Contributor Author

odersky commented Mar 2, 2018

@Blaisorblade scalac's inference is too different to be able to answer that question.

@odersky
Copy link
Contributor Author

odersky commented Mar 2, 2018

test performance please

@dottybot
Copy link
Member

dottybot commented Mar 2, 2018

performance test scheduled: 1 job(s) in queue, 0 running.

@odersky
Copy link
Contributor Author

odersky commented Mar 2, 2018

I changed the algorithm to be less arbitrary than what was in the initial PR.

@dottybot
Copy link
Member

dottybot commented Mar 2, 2018

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/4059/ to see the changes.

Benchmarks is based on merging with master (7655503)

else {
val otherParam = tv.origin
val fs1 = if (constraint.isLess(tparam, otherParam)) fs &~ Covariant else fs
val fs2 = if (constraint.isLess(otherParam, tparam)) fs1 &~ Contravariant else fs1
Copy link
Contributor

Choose a reason for hiding this comment

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

@odersky We were wondering about

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.

Are you trying to give the biggest type to the typing context? If so, do you know the variance of tv's occurrences in the typing context? It could occur in either covariant or contravariant positions, and that affects the polarity of occurrences of tvar in tv's bounds, but it doesn't look like tvar's polarity is accounted for...

@@ -313,6 +313,29 @@ object Inferencing {

propagate(accu(SimpleIdentityMap.Empty, tp))
}

private def varianceInContext(tvar: TypeVar)(implicit ctx: Context): FlagSet = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add documentation for this method

@allanrenucci
Copy link
Contributor

Merging this to fix the regression before the release.

Code in this PR will be removed in #4065, so no need to further document it.

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.

4 participants