-
Notifications
You must be signed in to change notification settings - Fork 1.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
Fixes and tweaks to implicit priority change scheme #21328
Conversation
@WojciechMazur Can we get OpenCB results also for the two commits in this PR. Ideally first ffff15c and then 37dd612. My theory is that they would solve the uplicke problem and hopefully some other problems as well. |
Sure, I'll start the OpenCB |
Another comparison based on 3.5.0-RC6 + this PR New regressions:
Givens changes warnings:
When compared with other alternatives this solution seems to keep the most ambitious implicits and overall seems to give the most similar when comparing stats with 3.5.0-RC6 |
The crash in Tapir seems to be unrelated to implicits, it's probably just because some different code is generated now. Do you have the results from 3.5.0-RC6 for comparison? |
Is upickle compiling now or still failing? Most ambiguous is explainable since we now don't pick a winner in a given/implicit pair. These are treated as ambiguous, unless there is another overriding factor. |
5e14513
to
ff0b6b9
Compare
@Kordyjan This is the PR we will go with for 3.5. It implements the delay of the switchover that we discussed. |
// Intermediate rules: better means specialize, but map all type arguments downwards | ||
// These are enabled for 3.0-3.5, and for all comparisons between old-style implicits, | ||
// and in 3.5 and 3.6-migration when we compare with previous rules. | ||
if scheme == CompareScheme.Intermediate || alt1IsImplicit then |
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.
if scheme == CompareScheme.Intermediate || alt1IsImplicit then | |
if scheme == CompareScheme.Intermediate then |
Is it intentional that we still do the CompareScheme.Intermediate
when specifically alt1 is an implicit ?
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.
Yes! The idea is that for implicit/givens pairs we do the rules according to the left operand. Say an implicit I is more specialized than a given G. Then I wins by type against G but G also wins by type against I. So it's a draw in the end.
But in more complex situations it could be (for instance) that G doe not win against I because there are some variable's to instantiate on I but not on G. So I wins. (or G, vice versa). The PR comment mentions this.
I am testing a fix to disambiguate as we discussed. Let's try that and if
that fails the CI we can fallback to this PR.
…On Tue, Aug 6, 2024 at 7:54 PM Eugene Flesselle ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In tests/neg/i21212.scala
<#21328 (comment)>:
> @@ -0,0 +1,11 @@
+//> using options -source 3.7
+object Minimization:
+
+ trait A
+ trait B extends A
+
+ def test1(using a1: A)(using b1: B) = summon[A] // picks (most general) a1
+ def test2(using a2: A)(implicit b2: B) = summon[A] // error: ambiguous
Oh my bad, they in fact do *not*, I had simply forgotten to use
-source:3.7, sorry about that
I will add the test back
—
Reply to this email directly, view it on GitHub
<#21328 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGCKVRBIYETFG7E3D5K3VLZQEEUNAVCNFSM6AAAAABL75WTICVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDEMRRHEZDKNZRHE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
Martin Odersky
Professor, Programming Methods Group (LAMP)
Faculty IC, EPFL
Station 14, Lausanne, Switzerland
|
@odersky I initially implemented what we had proposed for |
We now use a left-biased scheme, as follows. From 3.6 on: - A given x: X is better than a given or implicit y: Y if y can be instantiated/widened to X. - An implicit x: X is better than a given or implicit y: Y if y can be instantiated to a supertype of X. - Use owner score for givens as a tie breaker if after all other tests we still have an ambiguity. This is not transitive, so we need a separate scheme to work around that. Other change: - Drop special handling of NotGiven in prioritization. The previous logic pretended to do so, but was ineffective.
We only have transitivity between givens or between implicits. To cope with that - We tank first all implicits, giving a best implicit search result. - Then we rank all givens startign with the implicit result. If there is a given that is better than the best implicit, the best given will be chosen. Otherwise we will stick with the best implicit.
Warnings from 3.6, change in 3.7. This is one version later than originally planned.
c94ffac
to
58545eb
Compare
Make the wording of a priority change warning message stable under different orders of eligibles. We now always report the previously chosen alternative first and the new one second. Note: We can still get ambiguities by fallging different pairs of alternatives depending on initial order.
58545eb
to
f5f390e
Compare
case fail: SearchFailure => | ||
fail.reason match | ||
case ambi: AmbiguousImplicits => | ||
if compareAlternatives(ambi.alt1, alt2, disambiguate = true) < 0 |
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.
I think this would be the expected behavior for disambiguate
- when coming from
healAmbiguous
from a standard ambiguity case, that is, for the current search; - but not when coming from
healAmbiguous
from an ambiguity which happened in a nested search.
In the latter case, we would then be comparing alt2
to alternatives for an unrelated expected type.
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.
How about we make use disambiguate = true for compareAlternatives when healing nested implicits?
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.
As far as I can tell, that would mean potentially faulty as in false positive (but never missing) warnings for a change in resolution in the nested search
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.
Perhaps we could do the check twice only in the 3.7-migration
version, and keep the single check in 3.6
for better performance
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.
Indeed. In light of this, I think we should go with #49. Can you rebase it on the current state?
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.
Can you rebase it on the current state?
Yes, will do that right now + plus first checking if we are in a migration version before the second comparison
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.
I've pushed the changes (on #49) after the rebase, the optimization for versions staring from 3.7
, and some documentation.
0361991
to
f5f390e
Compare
Superseded by #21339. |
Based on #21328: We now use a left-biased scheme, as follows. From 3.7 on: A given x: X is better than a given or implicit y: Y if y can be instantiated/widened to X. An implicit x: X is better than a given or implicit y: Y if y can be instantiated to a supertype of X. Use owner score for givens as a tie breaker if after all other tests we still have an ambiguity. This is not transitive, but the PR implements a scheme to work around that. Other changes: - Drop special handling of NotGiven in prioritization. The previous logic pretended to do so, but was ineffective. - Fix healAmbiguous to compareAlternatives with disambiguate = true, to account for changes made in #21045
We now use a left-biased scheme, as follows.
From 3.7 on:
This is not transitive, but the PR implements a scheme to work around that.
Other change: