@@ -658,7 +658,9 @@ object TypeOps:
658658 * Otherwise, return NoType.
659659 */
660660 private def instantiateToSubType (tp1 : NamedType , tp2 : Type )(using Context ): Type = {
661- /** expose abstract type references to their bounds or tvars according to variance */
661+ // In order for a child type S to qualify as a valid subtype of the parent
662+ // T, we need to test whether it is possible S <: T. Therefore, we replace
663+ // type parameters in T with tvars, and see if the subtyping is true.
662664 val approximateTypeParams = new TypeMap {
663665 val boundTypeParams = util.HashMap [TypeRef , TypeVar ]()
664666
@@ -683,15 +685,31 @@ object TypeOps:
683685 end if
684686
685687 case AppliedType (tycon : TypeRef , _) if ! tycon.dealias.typeSymbol.isClass =>
686- // Type inference cannot handle X[Y] <:< Int
687- // See tests/patmat/i3645g.scala
688+
689+ // In tests/patmat/i3645g.scala, we need to tell whether it's possible
690+ // that K1 <: K[Foo]. If yes, we issue a warning; otherwise, no
691+ // warnings.
692+ //
693+ // - K1 <: K[Foo] is possible <==>
694+ // - K[Int] <: K[Foo] is possible <==>
695+ // - Int <: Foo is possible <==>
696+ // - Int <: Module.Foo.Type is possible
697+ //
698+ // If we remove this special case, we will encounter the case Int <:
699+ // X[Y], where X and Y are tvars. The subtype checking will simply
700+ // return false. But depending on the bounds of X and Y, the subtyping
701+ // can be true.
702+ //
703+ // As a workaround, we approximate higher-kinded type parameters with
704+ // the value types that can be instantiated from its bounds.
705+
688706 val bounds : TypeBounds = tycon.underlying match {
689707 case TypeBounds (tl1 : HKTypeLambda , tl2 : HKTypeLambda ) =>
690- TypeBounds (tl1.resType, tl2.resType )
708+ TypeBounds (defn. NothingType , defn. AnyKindType )
691709 case TypeBounds (tl1 : HKTypeLambda , tp2) =>
692- TypeBounds (tl1.resType , tp2)
710+ TypeBounds (defn. NothingType , tp2)
693711 case TypeBounds (tp1, tl2 : HKTypeLambda ) =>
694- TypeBounds (tp1, tl2.resType )
712+ TypeBounds (tp1, defn. AnyKindType )
695713 }
696714
697715 newTypeVar(bounds)
@@ -730,7 +748,7 @@ object TypeOps:
730748 // refine subtype checking to eliminate abstract types according to
731749 // variance. As this logic is only needed in exhaustivity check,
732750 // we manually patch subtyping check instead of changing TypeComparer.
733- // See tests/patmat/3645b .scala
751+ // See tests/patmat/i3645b .scala
734752 def parentQualify (tp1 : Type , tp2 : Type ) = tp1.widen.classSymbol.info.parents.exists { parent =>
735753 parent.argInfos.nonEmpty && approximateTypeParams(parent) <:< tp2
736754 }
0 commit comments