@@ -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,15 +685,31 @@ 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
+
688
706
val bounds : TypeBounds = tycon.underlying match {
689
707
case TypeBounds (tl1 : HKTypeLambda , tl2 : HKTypeLambda ) =>
690
- TypeBounds (tl1.resType, tl2.resType )
708
+ TypeBounds (defn. NothingType , defn. AnyKindType )
691
709
case TypeBounds (tl1 : HKTypeLambda , tp2) =>
692
- TypeBounds (tl1.resType , tp2)
710
+ TypeBounds (defn. NothingType , tp2)
693
711
case TypeBounds (tp1, tl2 : HKTypeLambda ) =>
694
- TypeBounds (tp1, tl2.resType )
712
+ TypeBounds (tp1, defn. AnyKindType )
695
713
}
696
714
697
715
newTypeVar(bounds)
@@ -730,7 +748,7 @@ object TypeOps:
730
748
// refine subtype checking to eliminate abstract types according to
731
749
// variance. As this logic is only needed in exhaustivity check,
732
750
// we manually patch subtyping check instead of changing TypeComparer.
733
- // See tests/patmat/3645b .scala
751
+ // See tests/patmat/i3645b .scala
734
752
def parentQualify (tp1 : Type , tp2 : Type ) = tp1.widen.classSymbol.info.parents.exists { parent =>
735
753
parent.argInfos.nonEmpty && approximateTypeParams(parent) <:< tp2
736
754
}
0 commit comments