Skip to content

Commit

Permalink
Don't instantiate hk type constructors too early
Browse files Browse the repository at this point in the history
The issue #6385 contains more explanations.
  • Loading branch information
odersky authored and smarter committed May 17, 2019
1 parent c8eb14f commit 18ce5d2
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 13 deletions.
10 changes: 0 additions & 10 deletions compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
Original file line number Diff line number Diff line change
Expand Up @@ -520,16 +520,6 @@ trait ConstraintHandling[AbstractContext] {
}
}

/** Instantiate `param` to `tp` if the constraint stays satisfiable */
protected def tryInstantiate(param: TypeParamRef, tp: Type)(implicit actx: AbstractContext): Boolean = {
val saved = constraint
constraint =
if (addConstraint(param, tp, fromBelow = true) &&
addConstraint(param, tp, fromBelow = false)) constraint.replace(param, tp)
else saved
constraint ne saved
}

/** Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated */
def checkPropagated(msg: => String)(result: Boolean)(implicit actx: AbstractContext): Boolean = {
if (Config.checkConstraintsPropagated && result && addConstraintInvocations == 0) {
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
tycon1.dealiasKeepRefiningAnnots match {
case tycon1: TypeParamRef =>
(tycon1 == tycon2 ||
canConstrain(tycon1) && tryInstantiate(tycon1, tycon2)) &&
canConstrain(tycon1) && isSubType(tycon1, tycon2)) &&
isSubArgs(args1, args2, tp1, tparams)
case tycon1: TypeRef =>
tycon2.dealiasKeepRefiningAnnots match {
Expand Down Expand Up @@ -892,7 +892,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
tl => tparams1.map(tparam => tl.integrate(tparams, tparam.paramInfo).bounds),
tl => tp1base.tycon.appliedTo(args1.take(lengthDiff) ++
tparams1.indices.toList.map(tl.paramRefs(_))))
(assumedTrue(tycon2) || tryInstantiate(tycon2, tycon1.ensureLambdaSub)) &&
(assumedTrue(tycon2) || isSubType(tycon1.ensureLambdaSub, tycon2)) &&
recur(tp1, tycon1.appliedTo(args2))
}
}
Expand Down Expand Up @@ -977,7 +977,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
case param1: TypeParamRef =>
def canInstantiate = tp2 match {
case AppliedType(tycon2, args2) =>
tryInstantiate(param1, tycon2.ensureLambdaSub) && isSubArgs(args1, args2, tp1, tycon2.typeParams)
isSubType(param1, tycon2.ensureLambdaSub) && isSubArgs(args1, args2, tp1, tycon2.typeParams)
case _ =>
false
}
Expand Down
1 change: 1 addition & 0 deletions compiler/test/dotc/pos-test-pickling.blacklist
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
i94-nada.scala
i1812.scala
i1867.scala
i3067.scala
Expand Down
1 change: 1 addition & 0 deletions compiler/test/dotty/tools/dotc/CompilationTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ class CompilationTests extends ParallelTesting {
compileFile("tests/neg-custom-args/nopredef.scala", defaultOptions.and("-Yno-predef")),
compileFile("tests/neg-custom-args/noimports.scala", defaultOptions.and("-Yno-imports")),
compileFile("tests/neg-custom-args/noimports2.scala", defaultOptions.and("-Yno-imports")),
compileFile("tests/neg-custom-args/i1650.scala", allowDeepSubtypes),
compileFile("tests/neg-custom-args/i3882.scala", allowDeepSubtypes),
compileFile("tests/neg-custom-args/i4372.scala", allowDeepSubtypes),
compileFile("tests/neg-custom-args/i1754.scala", allowDeepSubtypes),
Expand Down
File renamed without changes.
11 changes: 11 additions & 0 deletions tests/neg/i6385a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Box[F[_]]

class C[X]
class D[X] extends C[String]

object Test {
def f[F[_]](x: Box[F]) = ???
def db: Box[D] = ???
def cb: Box[C] = db // error
f[[X] => C[X]](db) // error
}
File renamed without changes.
17 changes: 17 additions & 0 deletions tests/pos/i6385.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
trait Tc1[A]
trait Tc2[A] extends Tc1[A]

class PinTypeTo[K[_]]
object PinTypeTo {
implicit val pinType: PinTypeTo[Tc2] = new PinTypeTo[Tc2]
}

class X
object X {
implicit def Tc2Instance[F[x] >: Tc2[x]: PinTypeTo]: F[X] = new Tc2[X] {}
}

object app extends App {
implicitly[Tc2[X]] // ok
implicitly[Tc1[X]]//(X.Tc2Instance[Tc2]) // fails
}

0 comments on commit 18ce5d2

Please sign in to comment.