diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index d9bff78ff9a3..58d009708e36 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -1250,7 +1250,7 @@ trait Implicits: val arity2 = sym2.info.firstParamTypes.length if arity1 < arity2 then return true if arity1 > arity2 then return false - compareOwner(sym1, sym2) == 1 + compareOwner(sym1.owner, sym2.owner) == 1 /** Sort list of implicit references according to `prefer`. * This is just an optimization that aims at reducing the average diff --git a/tests/pos/i10964.scala b/tests/pos/i10964.scala new file mode 100644 index 000000000000..368659e12510 --- /dev/null +++ b/tests/pos/i10964.scala @@ -0,0 +1,48 @@ +trait Applicative[F[_]] + +trait FooT[F[_], A] +trait BarT[F[_], A] +trait QuxT[F[_], A] +trait BazT[F[_], A] +trait ZepT[F[_], A] +trait JazT[F[_], A] +trait LafT[F[_], A] +trait PogT[F[_], A] + +trait Sync[F[_]] +object Sync { + implicit def syncForFooT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> FooT[F, X]] = ??? + implicit def syncForBarT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> BarT[F, X]] = ??? + implicit def syncForQuxT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> QuxT[F, X]] = ??? + implicit def syncForBazT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> BazT[F, X]] = ??? + implicit def syncForZepT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> ZepT[F, X]] = ??? + implicit def syncForJazT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> JazT[F, X]] = ??? + // defining additional implicits beyond the 6 above seems to result in hang/OOM + implicit def syncForLafT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> LafT[F, X]] = ??? + implicit def syncForPogT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> PogT[F, X]] = ??? +} + +trait Ref[F[_], A] +object Ref { + trait Make[F[_]] + object Make extends MakeInstances + + trait MakeInstances extends MakeLowPriorityInstances { + implicit def applicativeInstance[F[_]](implicit F: Applicative[F]): Make[F] = ??? + } + + trait MakeLowPriorityInstances { + implicit def syncInstance[F[_]](implicit F: Sync[F]): Make[F] = ??? + } + + def of[F[_], A](a: A)(implicit mk: Make[F]): F[Ref[F, A]] = ??? +} + +class Resource[F[_], A] { + implicit def syncForResource[F[_]](implicit F0: Sync[F]): Sync[[X] =>> Resource[F, X]] = ??? + + def foo(x: F[Unit])(implicit F: Applicative[F]) = { + Ref.of /*[F, (F[Unit], F[Unit])]*/ ((x, x)) + () + } +} \ No newline at end of file diff --git a/tests/pos/i10964a.scala b/tests/pos/i10964a.scala new file mode 100644 index 000000000000..55ba1a47d266 --- /dev/null +++ b/tests/pos/i10964a.scala @@ -0,0 +1,68 @@ +trait Monoid[A] +trait Semigroup[A] +trait Applicative[F[_]] + +trait OptionT[F[_], A] +trait EitherT[F[_], A, B] +trait IorT[F[_], A, B] +trait WriterT[F[_], L, V] +trait Kleisli[F[_], A, B] + +final class ApplicativeIdOps[A](private val a: A) extends AnyVal { + def pure[F[_]](implicit F: Applicative[F]): F[A] = ??? +} + +object ApplicativeSyntax { + implicit final def syntaxApplicativeId[A](a: A): ApplicativeIdOps[A] = new ApplicativeIdOps[A](a) +} + +trait Sync[F[_]] + +object Sync { + implicit def syncForOptionT[F[_]](implicit F0: Sync[F]): Sync[[X] =>> OptionT[F, X]] = ??? + implicit def syncForEitherT[F[_], E](implicit F0: Sync[F]): Sync[[X] =>> EitherT[F, E, X]] = ??? + implicit def syncForIorT[F[_], L](implicit F0: Sync[F], L0: Semigroup[L]): Sync[[X] =>> IorT[F, L, X]] = ??? + implicit def syncForWriterT[F[_], L](implicit F0: Sync[F], L0: Monoid[L]): Sync[[X] =>> WriterT[F, L, X]] = ??? + implicit def syncForKleisli[F[_], R](implicit F0: Sync[F]): Sync[[X] =>> Kleisli[F, R, X]] = ??? +} + +trait Async[F[_]] extends Sync[F] + +object Async { + implicit def asyncForOptionT[F[_]](implicit F0: Async[F]): Async[[X] =>> OptionT[F, X]] = ??? + implicit def asyncForEitherT[F[_], E](implicit F0: Async[F]): Async[[X] =>> EitherT[F, E, X]] = ??? + implicit def asyncForIorT[F[_], L](implicit F0: Async[F], L0: Semigroup[L]): Async[[X] =>> IorT[F, L, X]] = ??? + implicit def asyncForWriterT[F[_], L](implicit F0: Async[F], L0: Monoid[L]): Async[[X] =>> WriterT[F, L, X]] = ??? + implicit def asyncForKleisli[F[_], R](implicit F0: Async[F]): Async[[X] =>> Kleisli[F, R, X]] = ??? +} + +trait Concurrent[F[_], E] extends Applicative[F] + +trait Ref[F[_], A] + +object Ref { + trait Make[F[_]] + object Make extends MakeInstances + + trait MakeInstances extends MakeLowPriorityInstances { + implicit def concurrentInstance[F[_]](implicit F: Concurrent[F, _]): Make[F] = ??? + } + + trait MakeLowPriorityInstances { + implicit def syncInstance[F[_]](implicit F: Sync[F]): Make[F] = ??? + } + + def of[F[_], A](a: A)(implicit mk: Make[F]): F[Ref[F, A]] = ??? +} + + +class Resource[F[_], A] { + import ApplicativeSyntax._ + + implicit def asyncForResource[F[_]](implicit F0: Async[F]): Async[[X] =>> Resource[F, X]] = ??? + + def parZip(implicit F: Concurrent[F, Throwable]) = { + Ref.of /*[F, (F[Unit], F[Unit])]*/ (().pure[F] -> ().pure[F]) + () + } +} \ No newline at end of file