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

Fix compilation under Scala 3.6 new givens prioritization scheme #238

Merged
merged 1 commit into from
Jul 18, 2024

Conversation

WojciechMazur
Copy link
Contributor

@WojciechMazur WojciechMazur commented Jul 18, 2024

Applies a patch required after merge of scala/scala3#19300 to one of the tests to make it compile under Scala 3.6 in the Scala 3 Open Community Build. This change is a cherry-pick from a Scala 3 Small / Managed Communty Build run on the fork of this project

@@ -63,7 +63,7 @@ class InstancesTests:

@Test
def mapKforSingle: Unit =
val inst = summon[K0.Instances[TypeClass, Single[Int]]]
val inst = summon[K0.ProductInstances[TypeClass, Single[Int]]]
Copy link
Member

Choose a reason for hiding this comment

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

Why is the change required? What's wrong with the original implementation?
I think if this test is broken, it would be broken for users too.

Copy link
Contributor Author

@WojciechMazur WojciechMazur Jul 18, 2024

Choose a reason for hiding this comment

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

It all comes to how the implicit are resolved, in short let's start with a description from PR:

Instead of requiring an argument to be most specific, we now require it to be most general while still conforming to the formal parameter.
...
Intuitively, we want to get the closest possible match between required formal parameter type and synthetisized argument. The "most general" rule provides that.

In shapeless there is defined a given method creating both K0.Instances and K0.ProductInstances
Under the old implicit rule, we were getting granted the most specific available type, in our case that's ProductInstances, so even though there exists inline given mkInstances[F[_], T](using gen: Generic[T]): Instances[F, T] it would never be picked, instead, the compiler would always choose inline given mkProductInstances[F[_], T](using gen: ProductGeneric[T]): ProductInstances[F, T]

Now, since 3.6 when asked for K0.Instances and when having an access to instance of this type directly, compiler would choose it instead of using it's more specific subtype.

Because of this single change, the result of the summon has changed. We no longer have access to ProductInstances but to the Instances. Now in the next few lines when we try to use foldLeft on transformed values, we get to the clue of the problem - there is no instance of Foldable instance defined for K0.Instances so the compilation files with type mismatch.

Overall it's very similar to the case from the PR's snippert:

class A
class B extends A
class C extends A

@main def Test = 
   given A = A()
   given B = B()
   def f0(using a: A, b: B) = ()
   f0 // evaluates to f(using given B, given B)
   
   given C = C()
   def f1(using a: A, b: B, c: C) = ()
   f1 // error: ambiguous implicits, compiler cannot choose between given B and given C to use for argument `a`

In the case of shapeless the only difference was that both ProductInstances and CoproductInstances could have never been constructed at the same time, which allowed for compilation.

Probably using method similar toK0.mkInstances[?, ?] after making it transparent inline but not given should be a decent workaround instead of using summon[K0.Instances[?, ?]]

Copy link
Member

Choose a reason for hiding this comment

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

Ah yes, thanks - foldLeft is missing from Instances. That's fine.

@joroKr21 joroKr21 merged commit dbf51f4 into typelevel:main Jul 18, 2024
6 checks passed
@WojciechMazur WojciechMazur deleted the fix/scala-3.6 branch July 18, 2024 18:23
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.

2 participants