Skip to content

Commit 5fa62fa

Browse files
authored
Merge pull request #10977 from dotty-staging/fix-#10964
Fix owner comparison when sorting eligible implicits
2 parents a438ec4 + 36fb21d commit 5fa62fa

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1250,7 +1250,7 @@ trait Implicits:
12501250
val arity2 = sym2.info.firstParamTypes.length
12511251
if arity1 < arity2 then return true
12521252
if arity1 > arity2 then return false
1253-
compareOwner(sym1, sym2) == 1
1253+
compareOwner(sym1.owner, sym2.owner) == 1
12541254

12551255
/** Sort list of implicit references according to `prefer`.
12561256
* This is just an optimization that aims at reducing the average

tests/pos/i10964.scala

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
trait Applicative[F[_]]
2+
3+
trait FooT[F[_], A]
4+
trait BarT[F[_], A]
5+
trait QuxT[F[_], A]
6+
trait BazT[F[_], A]
7+
trait ZepT[F[_], A]
8+
trait JazT[F[_], A]
9+
trait LafT[F[_], A]
10+
trait PogT[F[_], A]
11+
12+
trait Sync[F[_]]
13+
object Sync {
14+
implicit def syncForFooT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> FooT[F, X]] = ???
15+
implicit def syncForBarT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> BarT[F, X]] = ???
16+
implicit def syncForQuxT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> QuxT[F, X]] = ???
17+
implicit def syncForBazT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> BazT[F, X]] = ???
18+
implicit def syncForZepT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> ZepT[F, X]] = ???
19+
implicit def syncForJazT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> JazT[F, X]] = ???
20+
// defining additional implicits beyond the 6 above seems to result in hang/OOM
21+
implicit def syncForLafT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> LafT[F, X]] = ???
22+
implicit def syncForPogT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> PogT[F, X]] = ???
23+
}
24+
25+
trait Ref[F[_], A]
26+
object Ref {
27+
trait Make[F[_]]
28+
object Make extends MakeInstances
29+
30+
trait MakeInstances extends MakeLowPriorityInstances {
31+
implicit def applicativeInstance[F[_]](implicit F: Applicative[F]): Make[F] = ???
32+
}
33+
34+
trait MakeLowPriorityInstances {
35+
implicit def syncInstance[F[_]](implicit F: Sync[F]): Make[F] = ???
36+
}
37+
38+
def of[F[_], A](a: A)(implicit mk: Make[F]): F[Ref[F, A]] = ???
39+
}
40+
41+
class Resource[F[_], A] {
42+
implicit def syncForResource[F[_]](implicit F0: Sync[F]): Sync[[X] =>> Resource[F, X]] = ???
43+
44+
def foo(x: F[Unit])(implicit F: Applicative[F]) = {
45+
Ref.of /*[F, (F[Unit], F[Unit])]*/ ((x, x))
46+
()
47+
}
48+
}

tests/pos/i10964a.scala

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
trait Monoid[A]
2+
trait Semigroup[A]
3+
trait Applicative[F[_]]
4+
5+
trait OptionT[F[_], A]
6+
trait EitherT[F[_], A, B]
7+
trait IorT[F[_], A, B]
8+
trait WriterT[F[_], L, V]
9+
trait Kleisli[F[_], A, B]
10+
11+
final class ApplicativeIdOps[A](private val a: A) extends AnyVal {
12+
def pure[F[_]](implicit F: Applicative[F]): F[A] = ???
13+
}
14+
15+
object ApplicativeSyntax {
16+
implicit final def syntaxApplicativeId[A](a: A): ApplicativeIdOps[A] = new ApplicativeIdOps[A](a)
17+
}
18+
19+
trait Sync[F[_]]
20+
21+
object Sync {
22+
implicit def syncForOptionT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> OptionT[F, X]] = ???
23+
implicit def syncForEitherT[F[_], E](implicit F0: Sync[F]): Sync[[X] =>> EitherT[F, E, X]] = ???
24+
implicit def syncForIorT[F[_], L](implicit F0: Sync[F], L0: Semigroup[L]): Sync[[X] =>> IorT[F, L, X]] = ???
25+
implicit def syncForWriterT[F[_], L](implicit F0: Sync[F], L0: Monoid[L]): Sync[[X] =>> WriterT[F, L, X]] = ???
26+
implicit def syncForKleisli[F[_], R](implicit F0: Sync[F]): Sync[[X] =>> Kleisli[F, R, X]] = ???
27+
}
28+
29+
trait Async[F[_]] extends Sync[F]
30+
31+
object Async {
32+
implicit def asyncForOptionT[F[_]](implicit F0: Async[F]): Async[[X] =>> OptionT[F, X]] = ???
33+
implicit def asyncForEitherT[F[_], E](implicit F0: Async[F]): Async[[X] =>> EitherT[F, E, X]] = ???
34+
implicit def asyncForIorT[F[_], L](implicit F0: Async[F], L0: Semigroup[L]): Async[[X] =>> IorT[F, L, X]] = ???
35+
implicit def asyncForWriterT[F[_], L](implicit F0: Async[F], L0: Monoid[L]): Async[[X] =>> WriterT[F, L, X]] = ???
36+
implicit def asyncForKleisli[F[_], R](implicit F0: Async[F]): Async[[X] =>> Kleisli[F, R, X]] = ???
37+
}
38+
39+
trait Concurrent[F[_], E] extends Applicative[F]
40+
41+
trait Ref[F[_], A]
42+
43+
object Ref {
44+
trait Make[F[_]]
45+
object Make extends MakeInstances
46+
47+
trait MakeInstances extends MakeLowPriorityInstances {
48+
implicit def concurrentInstance[F[_]](implicit F: Concurrent[F, _]): Make[F] = ???
49+
}
50+
51+
trait MakeLowPriorityInstances {
52+
implicit def syncInstance[F[_]](implicit F: Sync[F]): Make[F] = ???
53+
}
54+
55+
def of[F[_], A](a: A)(implicit mk: Make[F]): F[Ref[F, A]] = ???
56+
}
57+
58+
59+
class Resource[F[_], A] {
60+
import ApplicativeSyntax._
61+
62+
implicit def asyncForResource[F[_]](implicit F0: Async[F]): Async[[X] =>> Resource[F, X]] = ???
63+
64+
def parZip(implicit F: Concurrent[F, Throwable]) = {
65+
Ref.of /*[F, (F[Unit], F[Unit])]*/ (().pure[F] -> ().pure[F])
66+
()
67+
}
68+
}

0 commit comments

Comments
 (0)