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

Test: Revert to intermediate priotization scheme. #20276

Closed
wants to merge 1 commit into from

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Apr 27, 2024

#19300 contained force-pushes that changed the behavior of the open CB. Creating a separate branch for the state when open CB run for the first time.

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.
@odersky odersky marked this pull request as draft April 27, 2024 17:59
@odersky odersky closed this Apr 30, 2024
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.

None yet

1 participant