Skip to content

Commit 9ecacb1

Browse files
authored
Merge pull request #13663 from dotty-staging/fix-13660
Remember compared polytypes
2 parents 85d444e + 45c7d68 commit 9ecacb1

File tree

4 files changed

+39
-10
lines changed

4 files changed

+39
-10
lines changed

community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class CommunityBuildTestB:
4545
@Test def fs2 = projects.fs2.run()
4646
@Test def munit = projects.munit.run()
4747
@Test def munitCatsEffect = projects.munitCatsEffect.run()
48-
// @Test def perspective = projects.perspective.run()
48+
@Test def perspective = projects.perspective.run()
4949
@Test def scalacheckEffect = projects.scalacheckEffect.run()
5050
@Test def scodec = projects.scodec.run()
5151
@Test def scodecBits = projects.scodecBits.run()

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
184184
val bounds = gadtBounds(sym)
185185
bounds != null && op(bounds)
186186

187+
private inline def comparingTypeLambdas(tl1: TypeLambda, tl2: TypeLambda)(op: => Boolean): Boolean =
188+
val saved = comparedTypeLambdas
189+
comparedTypeLambdas += tl1
190+
comparedTypeLambdas += tl2
191+
try op finally comparedTypeLambdas = saved
192+
187193
protected def isSubType(tp1: Type, tp2: Type, a: ApproxState): Boolean = {
188194
val savedApprox = approx
189195
val savedLeftRoot = leftRoot
@@ -629,12 +635,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
629635
migrateTo3 ||
630636
tp1.typeParams.corresponds(tp2.typeParams)((tparam1, tparam2) =>
631637
isSubType(tparam2.paramInfo.subst(tp2, tp1), tparam1.paramInfo))
632-
val saved = comparedTypeLambdas
633-
comparedTypeLambdas += tp1
634-
comparedTypeLambdas += tp2
635-
val variancesOK = variancesConform(tp1.typeParams, tp2.typeParams)
636-
try variancesOK && boundsOK && isSubType(tp1.resType, tp2.resType.subst(tp2, tp1))
637-
finally comparedTypeLambdas = saved
638+
comparingTypeLambdas(tp1, tp2) {
639+
val variancesOK = variancesConform(tp1.typeParams, tp2.typeParams)
640+
variancesOK && boundsOK && isSubType(tp1.resType, tp2.resType.subst(tp2, tp1))
641+
}
638642
case _ =>
639643
val tparams1 = tp1.typeParams
640644
if (tparams1.nonEmpty)
@@ -704,9 +708,11 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
704708
case tp2: PolyType =>
705709
def comparePoly = tp1 match {
706710
case tp1: PolyType =>
707-
(tp1.signature consistentParams tp2.signature) &&
708-
matchingPolyParams(tp1, tp2) &&
709-
isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1))
711+
comparingTypeLambdas(tp1, tp2) {
712+
(tp1.signature consistentParams tp2.signature)
713+
&& matchingPolyParams(tp1, tp2)
714+
&& isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1))
715+
}
710716
case _ => false
711717
}
712718
comparePoly

tests/pos/i13660.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
type Const[A] = [_] =>> A
2+
type FunctionK[A[_], B[_]] = [Z] => A[Z] => B[Z]
3+
4+
type #~>#:[T, R] = FunctionK[Const[T], Const[R]]
5+
6+
object FunctionK:
7+
def liftConst[A, B](f: A => B): /*FunctionK[Const[A], Const[B]]*/ A #~>#: B =
8+
[Z1] => (a: A) => f(a)
9+
10+
trait FoldableK[F[_[_], _]]:
11+
12+
def foldMapK1[A[_], C, B](fa: F[A, C])(f: FunctionK[A, Const[B]]): B
13+
14+
def toListK[A, C](fa: F[Const[A], C]): List[A] =
15+
foldMapK1(fa)(FunctionK.liftConst(List(_: A)))

tests/pos/i7888.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
def usingSeq[B](f: [A] => Seq[A] => B): B = {
2+
f(Nil)
3+
}
4+
def crash() = {
5+
usingSeq { [A] => (a: Seq[A]) =>
6+
a
7+
}
8+
}

0 commit comments

Comments
 (0)