-
Notifications
You must be signed in to change notification settings - Fork 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
Change rules for given prioritization #19300
Commits on May 1, 2024
-
Fix shapeless 3 deriving test.
Typo: mkInstances instead of mkProductInstances, previously got healed by accident because if most specific rule. Change rules for given prioritization Consider the following program: ```scala class A class B extends A class C extends A given A = A() given B = B() given C = C() def f(using a: A, b: B, c: C) = println(a.getClass) println(b.getClass) println(c.getClass) @main def Test = f ``` With the current rules, this would fail with an ambiguity error between B and C when trying to synthesize the A parameter. This is a problem without an easy remedy. We can fix this problem by flipping the priority for implicit arguments. Instead of requiring an argument to be most _specific_, we now require it to be most _general_ while still conforming to the formal parameter. There are three justifications for this change, which at first glance seems quite drastic: - It gives us a natural way to deal with inheritance triangles like the one in the code above. Such triangles are quite common. - Intuitively, we want to get the closest possible match between required formal parameter type and synthetisized argument. The "most general" rule provides that. - We already do a crucial part of this. Namely, with current rules we interpolate all type variables in an implicit argument downwards, no matter what their variance is. This makes no sense in theory, but solves hairy problems with contravariant typeclasses like `Comparable`. Instead of this hack, we now do something more principled, by flipping the direction everywhere, preferring general over specific, instead of just flipping contravariant type parameters. Don't flip contravariant type arguments for overloading resolution Flipping contravariant type arguments was needed for implicit search where it will be replaced by a more general scheme. But it makes no sense for overloading resolution. For overloading resolution, we want to pick the most specific alternative, analogous to us picking the most specific instantiation when we force a fully defined type. Disable implicit search everywhere for disambiaguation Previously, one disambiguation step missed that, whereas implicits were turned off everywhere else.
Configuration menu - View commit details
-
Copy full SHA for d4de2cb - Browse repository at this point
Copy the full SHA d4de2cbView commit details -
Change rules for given prioritization
Consider the following program: ```scala class A class B extends A class C extends A given A = A() given B = B() given C = C() def f(using a: A, b: B, c: C) = println(a.getClass) println(b.getClass) println(c.getClass) @main def Test = f ``` With the current rules, this would fail with an ambiguity error between B and C when trying to synthesize the A parameter. This is a problem without an easy remedy. We can fix this problem by flipping the priority for implicit arguments. Instead of requiring an argument to be most _specific_, we now require it to be most _general_ while still conforming to the formal parameter. There are three justifications for this change, which at first glance seems quite drastic: - It gives us a natural way to deal with inheritance triangles like the one in the code above. Such triangles are quite common. - Intuitively, we want to get the closest possible match between required formal parameter type and synthetisized argument. The "most general" rule provides that. - We already do a crucial part of this. Namely, with current rules we interpolate all type variables in an implicit argument downwards, no matter what their variance is. This makes no sense in theory, but solves hairy problems with contravariant typeclasses like `Comparable`. Instead of this hack, we now do something more principled, by flipping the direction everywhere, preferring general over specific, instead of just flipping contravariant type parameters. The behavior is dependent on the Scala version - Old behavior: up to 3.4 - New behavior: from 3.5, 3.5-migration warns on behavior change The CB builds under the new rules. One fix was needed for a shapeless 3 deriving test. There was a typo: mkInstances instead of mkProductInstances, which previously got healed by accident because of the most specific rule. Also: Don't flip contravariant type arguments for overloading resolution Flipping contravariant type arguments was needed for implicit search where it will be replaced by a more general scheme. But it makes no sense for overloading resolution. For overloading resolution, we want to pick the most specific alternative, analogous to us picking the most specific instantiation when we force a fully defined type. Also: Disable implicit search everywhere for disambiaguation Previously, one disambiguation step missed that, whereas implicits were turned off everywhere else.
Configuration menu - View commit details
-
Copy full SHA for 1b9a7e0 - Browse repository at this point
Copy the full SHA 1b9a7e0View commit details -
Configuration menu - View commit details
-
Copy full SHA for 7721833 - Browse repository at this point
Copy the full SHA 7721833View commit details -
Switch to new rules only if both sides are givens
(rather than implicits).
Configuration menu - View commit details
-
Copy full SHA for c54dbbf - Browse repository at this point
Copy the full SHA c54dbbfView commit details
Commits on May 5, 2024
-
Refine prioritization rules between givens and implicits
In the new system, givens always beat implicits when comparing value types. This is necessary to maintain two invariants in the new system: - When comparing old-style implicits nothing changes, we still use the old rules. - The isAsGood comparison is transitive. Exception: NotGiven has to be treated at lower priority.
Configuration menu - View commit details
-
Copy full SHA for b644d30 - Browse repository at this point
Copy the full SHA b644d30View commit details -
Delay roll-out of new prioritization scheme:
Now: 3.5: old scheme but warn if there are changes in the future 3.6-migration: new scheme, warn if prioritization has changed 3.6: new scheme, no warning
Configuration menu - View commit details
-
Copy full SHA for bc26c51 - Browse repository at this point
Copy the full SHA bc26c51View commit details -
Configuration menu - View commit details
-
Copy full SHA for 33f801b - Browse repository at this point
Copy the full SHA 33f801bView commit details
Commits on May 6, 2024
-
Avoid ambiguity errors arising from double references in implicits
If two implicit candidate references happen to be the same pick one of them instead of reporting an ambiguity.
Configuration menu - View commit details
-
Copy full SHA for 8a3854f - Browse repository at this point
Copy the full SHA 8a3854fView commit details