@@ -658,7 +658,9 @@ object TypeOps:
658
658
* Otherwise, return NoType.
659
659
*/
660
660
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.
662
664
val approximateTypeParams = new TypeMap {
663
665
val boundTypeParams = util.HashMap [TypeRef , TypeVar ]()
664
666
@@ -683,8 +685,27 @@ object TypeOps:
683
685
end if
684
686
685
687
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
+ //
706
+ // Note that `HKTypeLambda.resType` may contain TypeParamRef that are
707
+ // bound in the HKTypeLambda. This is fine, as the TypeComparer will
708
+ // recurse on the bounds of `TypeParamRef`.
688
709
val bounds : TypeBounds = tycon.underlying match {
689
710
case TypeBounds (tl1 : HKTypeLambda , tl2 : HKTypeLambda ) =>
690
711
TypeBounds (tl1.resType, tl2.resType)
@@ -730,7 +751,7 @@ object TypeOps:
730
751
// refine subtype checking to eliminate abstract types according to
731
752
// variance. As this logic is only needed in exhaustivity check,
732
753
// we manually patch subtyping check instead of changing TypeComparer.
733
- // See tests/patmat/3645b .scala
754
+ // See tests/patmat/i3645b .scala
734
755
def parentQualify (tp1 : Type , tp2 : Type ) = tp1.widen.classSymbol.info.parents.exists { parent =>
735
756
parent.argInfos.nonEmpty && approximateTypeParams(parent) <:< tp2
736
757
}
0 commit comments