Skip to content

Commit 756cd0a

Browse files
committed
Handle higher-kinded GADT bounds
It's a remainder from the effort to implement opaque types as GADTs. It has nothing to do with the new opaque type scheme but it fixes a missing piece: GADT constraints can affect higher-kinded type parameters, so these should be taken into account.
1 parent 6b7a1a7 commit 756cd0a

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

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

+11-6
Original file line numberDiff line numberDiff line change
@@ -830,9 +830,9 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
830830
* tp1 <:< tp2 using fourthTry (this might instantiate params in tp1)
831831
* tp1 <:< app2 using isSubType (this might instantiate params in tp2)
832832
*/
833-
def compareLower(tycon2bounds: TypeBounds, tyconIsTypeRef: Boolean): Boolean =
833+
def compareLower(tycon2bounds: TypeBounds, followSuperType: Boolean): Boolean =
834834
if ((tycon2bounds.lo `eq` tycon2bounds.hi) && !tycon2bounds.isInstanceOf[MatchAlias])
835-
if (tyconIsTypeRef) recur(tp1, tp2.superType)
835+
if (followSuperType) recur(tp1, tp2.superType)
836836
else isSubApproxHi(tp1, tycon2bounds.lo.applyIfParameterized(args2))
837837
else
838838
fallback(tycon2bounds.lo)
@@ -841,13 +841,15 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
841841
case param2: TypeParamRef =>
842842
isMatchingApply(tp1) ||
843843
canConstrain(param2) && canInstantiate(param2) ||
844-
compareLower(bounds(param2), tyconIsTypeRef = false)
844+
compareLower(bounds(param2), followSuperType = false)
845845
case tycon2: TypeRef =>
846846
isMatchingApply(tp1) ||
847847
defn.isTypelevel_S(tycon2.symbol) && compareS(tp2, tp1, fromBelow = true) || {
848848
tycon2.info match {
849849
case info2: TypeBounds =>
850-
compareLower(info2, tyconIsTypeRef = true)
850+
val gbounds2 = ctx.gadt.bounds(tycon2.symbol)
851+
if (gbounds2 == null) compareLower(info2, followSuperType = true)
852+
else compareLower(gbounds2 & info2, followSuperType = false)
851853
case info2: ClassInfo =>
852854
tycon2.name.toString.startsWith("Tuple") &&
853855
defn.isTupleType(tp2) && isSubType(tp1, tp2.toNestedPairs) ||
@@ -883,8 +885,11 @@ class TypeComparer(initctx: Context) extends ConstraintHandling {
883885
case tycon1: TypeRef =>
884886
val sym = tycon1.symbol
885887
!sym.isClass && (
886-
defn.isTypelevel_S(sym) && compareS(tp1, tp2, fromBelow = false) ||
887-
recur(tp1.superType, tp2))
888+
defn.isTypelevel_S(sym) && compareS(tp1, tp2, fromBelow = false) || {
889+
val gbounds1 = ctx.gadt.bounds(tycon1.symbol)
890+
if (gbounds1 == null) recur(tp1.superType, tp2)
891+
else recur((gbounds1.hi & tycon1.info.bounds.hi).applyIfParameterized(args1), tp2)
892+
})
888893
case tycon1: TypeProxy =>
889894
recur(tp1.superType, tp2)
890895
case _ =>

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ object Types {
563563
case _ =>
564564
go(tp.superType)
565565
}
566-
case tp: ThisType => // ??? inline
566+
case tp: ThisType =>
567567
goThis(tp)
568568
case tp: RefinedType =>
569569
if (name eq tp.refinedName) goRefined(tp) else go(tp.parent)

0 commit comments

Comments
 (0)