Skip to content

Commit

Permalink
Merge pull request #13323 from Linyxus/fix/hkt-bounds
Browse files Browse the repository at this point in the history
Better utilizing GADT bounds for HKTs
  • Loading branch information
abgruszecki authored Aug 31, 2021
2 parents 5b3c98f + d1a04e2 commit f8dec07
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 1 deletion.
21 changes: 20 additions & 1 deletion compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1167,13 +1167,25 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
else
fallback(tycon2bounds.lo)

def byGadtBounds: Boolean =
{
tycon2 match
case tycon2: TypeRef =>
val tycon2sym = tycon2.symbol
tycon2sym.onGadtBounds { bounds2 =>
inFrozenGadt { compareLower(bounds2, tyconIsTypeRef = false) }
}
case _ => false
} && { GADTused = true; true }

tycon2 match {
case param2: TypeParamRef =>
isMatchingApply(tp1) ||
canConstrain(param2) && canInstantiate(param2) ||
compareLower(bounds(param2), tyconIsTypeRef = false)
case tycon2: TypeRef =>
isMatchingApply(tp1) ||
byGadtBounds ||
defn.isCompiletimeAppliedType(tycon2.symbol) && compareCompiletimeAppliedType(tp2, tp1, fromBelow = true) || {
tycon2.info match {
case info2: TypeBounds =>
Expand Down Expand Up @@ -1213,11 +1225,18 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
isSubType(bounds(param1).hi.applyIfParameterized(args1), tp2, approx.addLow)
case tycon1: TypeRef =>
val sym = tycon1.symbol

def byGadtBounds: Boolean =
sym.onGadtBounds { bounds1 =>
inFrozenGadt { isSubType(bounds1.hi.applyIfParameterized(args1), tp2, approx.addLow) }
} && { GADTused = true; true }


!sym.isClass && {
defn.isCompiletimeAppliedType(sym) && compareCompiletimeAppliedType(tp1, tp2, fromBelow = false) ||
recur(tp1.superType, tp2) ||
tryLiftedToThis1
}
}|| byGadtBounds
case tycon1: TypeProxy =>
recur(tp1.superType, tp2)
case _ =>
Expand Down
8 changes: 8 additions & 0 deletions tests/pos/gadt-hkt-hi-bounds.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type Const = [X] =>> Int

trait Expr[-F[_]]
case class ConstExpr() extends Expr[Const]

def foo[F[_], A](e: Expr[F]) = e match
case _: ConstExpr =>
val i: Int = ??? : F[A]
7 changes: 7 additions & 0 deletions tests/pos/gadt-hkt-lo-bounds.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type Const = [X] =>> Int

trait Expr[+F[_]]
case class ConstExpr() extends Expr[Const]

def foo[F[_], A](e: Expr[F]): F[A] = e match
case _: ConstExpr => 0

0 comments on commit f8dec07

Please sign in to comment.