forked from scala/scala3
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix specifity comparison for extensions in polymorphic givens
When we compare polymorphic methods for specificity, we replace their type parameters by type variables constrained in the current context (see isAsSpecific), but for extension methods in polymorphic givens, the comparison was done with a constraint set that does not include the type parameters of the givens, this lead to ambiguity errors as experienced in typelevel/spotted-leopards#2. We fix this by ensuring the TyperState we use for the comparison contains any additional constraint specific to the TyperState of either alternative. This required generalizing TyperState#mergeConstraintWith to handle `this` not being committable (because in that case `this` does not need to take ownership of the type variables owned by `that`, therefore `that` itself is allowed to be committable).
- Loading branch information
Showing
4 changed files
with
77 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
trait Bla1[A]: | ||
extension (x: A) def foo(y: A): Int | ||
trait Bla2[A]: | ||
extension (x: A) def foo(y: A): Int | ||
|
||
def test = | ||
given bla1[T <: Int]: Bla1[T] = ??? | ||
given bla2[S <: Int]: Bla2[S] = ??? | ||
|
||
1.foo(2) // error: never extension is more specific than the other |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
trait Foo[F[_]]: | ||
extension [A](fa: F[A]) | ||
def foo[B](fb: F[B]): Int | ||
|
||
def test1 = | ||
// Simplified from https://github.com/typelevel/spotted-leopards/issues/2 | ||
given listFoo: Foo[List] with | ||
extension [A](fa: List[A]) | ||
def foo[B](fb: List[B]): Int = 1 | ||
|
||
given functionFoo[T]: Foo[[A] =>> T => A] with | ||
extension [A](fa: T => A) | ||
def foo[B](fb: T => B): Int = 2 | ||
|
||
val x = List(1, 2).foo(List(3, 4)) | ||
assert(x == 1, x) | ||
|
||
def test2 = | ||
// This test case would fail if we used `wildApprox` on the method types | ||
// instead of using the correct typer state. | ||
trait Bar1[A]: | ||
extension (x: A => A) def bar(y: A): Int | ||
trait Bar2: | ||
extension (x: Int => 1) def bar(y: Int): Int | ||
|
||
given bla1[T]: Bar1[T] with | ||
extension (x: T => T) def bar(y: T): Int = 1 | ||
given bla2: Bar2 with | ||
extension (x: Int => 1) def bar(y: Int): Int = 2 | ||
|
||
val f: Int => 1 = x => 1 | ||
val x = f.bar(1) | ||
assert(x == 2, x) | ||
|
||
@main def Test = | ||
test1 | ||
test2 |