@@ -48,16 +48,22 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
4848 private [this ] var totalCount = 0
4949
5050 private [this ] var myAnyClass : ClassSymbol = null
51+ private [this ] var myAnyKindClass : ClassSymbol = null
5152 private [this ] var myNothingClass : ClassSymbol = null
5253 private [this ] var myNullClass : ClassSymbol = null
5354 private [this ] var myObjectClass : ClassSymbol = null
5455 private [this ] var myAnyType : TypeRef = null
56+ private [this ] var myAnyKindType : TypeRef = null
5557 private [this ] var myNothingType : TypeRef = null
5658
5759 def AnyClass = {
5860 if (myAnyClass == null ) myAnyClass = defn.AnyClass
5961 myAnyClass
6062 }
63+ def AnyKindClass = {
64+ if (myAnyKindClass == null ) myAnyKindClass = defn.AnyKindClass
65+ myAnyKindClass
66+ }
6167 def NothingClass = {
6268 if (myNothingClass == null ) myNothingClass = defn.NothingClass
6369 myNothingClass
@@ -74,6 +80,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
7480 if (myAnyType == null ) myAnyType = AnyClass .typeRef
7581 myAnyType
7682 }
83+ def AnyKindType = {
84+ if (myAnyKindType == null ) myAnyKindType = AnyKindClass .typeRef
85+ myAnyKindType
86+ }
7787 def NothingType = {
7888 if (myNothingType == null ) myNothingType = NothingClass .typeRef
7989 myNothingType
@@ -367,19 +377,25 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
367377 case _ =>
368378 val cls2 = tp2.symbol
369379 if (cls2.isClass) {
370- if (cls2.typeParams.nonEmpty && tp1.isHK)
371- recur(tp1, EtaExpansion (cls2.typeRef))
372- else {
380+ if (cls2.typeParams.isEmpty) {
381+ if (cls2 eq AnyKindClass ) return true
382+ if (tp1.isRef(defn.NothingClass )) return true
383+ if (tp1.isLambdaSub) return false
384+ // Note: We would like to replace this by `if (tp1.hasHigherKind)`
385+ // but right now we cannot since some parts of the standard library rely on the
386+ // idiom that e.g. `List <: Any`. We have to bootstrap without scalac first.
373387 val base = tp1.baseType(cls2)
374- if (base.exists) {
375- if (cls2.is(JavaDefined ))
376- // If `cls2` is parameterized, we are seeing a raw type, so we need to compare only the symbol
377- return base.typeSymbol == cls2
378- if (base ne tp1)
379- return isSubType(base, tp2, if (tp1.isRef(cls2)) approx else approx.addLow)
380- }
388+ if (base.exists && base.ne(tp1))
389+ return isSubType(base, tp2, if (tp1.isRef(cls2)) approx else approx.addLow)
381390 if (cls2 == defn.SingletonClass && tp1.isStable) return true
382391 }
392+ else if (cls2.is(JavaDefined )) {
393+ // If `cls2` is parameterized, we are seeing a raw type, so we need to compare only the symbol
394+ val base = tp1.baseType(cls2)
395+ if (base.typeSymbol == cls2) return true
396+ }
397+ else if (tp1.isLambdaSub && ! tp1.isRef(defn.AnyKindClass ))
398+ return recur(tp1, EtaExpansion (cls2.typeRef))
383399 }
384400 fourthTry
385401 }
@@ -475,13 +491,11 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
475491 isSubType(tp1.resType, tp2.resType.subst(tp2, tp1))
476492 finally comparedTypeLambdas = saved
477493 case _ =>
478- if ( tp1.isHK) {
479- val tparams1 = tp1.typeParams
494+ val tparams1 = tp1.typeParams
495+ if ( tparams1.nonEmpty)
480496 return recur(
481497 HKTypeLambda .fromParams(tparams1, tp1.appliedTo(tparams1.map(_.paramRef))),
482- tp2
483- )
484- }
498+ tp2)
485499 else tp2 match {
486500 case EtaExpansion (tycon2) if tycon2.symbol.isClass =>
487501 return recur(tp1, tycon2)
@@ -540,7 +554,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
540554 def compareTypeBounds = tp1 match {
541555 case tp1 @ TypeBounds (lo1, hi1) =>
542556 ((lo2 eq NothingType ) || isSubType(lo2, lo1)) &&
543- ((hi2 eq AnyType ) || isSubType(hi1, hi2))
557+ ((hi2 eq AnyType ) && ! hi1.isLambdaSub || (hi2 eq AnyKindType ) || isSubType(hi1, hi2))
544558 case tp1 : ClassInfo =>
545559 tp2 contains tp1
546560 case _ =>
@@ -610,7 +624,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
610624 case EtaExpansion (tycon1) => recur(tycon1, tp2)
611625 case _ => tp2 match {
612626 case tp2 : HKTypeLambda => false // this case was covered in thirdTry
613- case _ => tp2.isHK && isSubType(tp1.resultType, tp2.appliedTo(tp1.paramRefs))
627+ case _ => tp2.isLambdaSub && isSubType(tp1.resultType, tp2.appliedTo(tp1.paramRefs))
614628 }
615629 }
616630 compareHKLambda
@@ -718,7 +732,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
718732 tl => tp1base.tycon.appliedTo(args1.take(lengthDiff) ++
719733 tparams1.indices.toList.map(tl.paramRefs(_))))
720734 (ctx.mode.is(Mode .TypevarsMissContext ) ||
721- tryInstantiate(tycon2, tycon1.ensureHK )) &&
735+ tryInstantiate(tycon2, tycon1.ensureLambdaSub )) &&
722736 recur(tp1, tycon1.appliedTo(args2))
723737 }
724738 }
@@ -801,7 +815,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
801815 case param1 : TypeParamRef =>
802816 def canInstantiate = tp2 match {
803817 case AppliedType (tycon2, args2) =>
804- tryInstantiate(param1, tycon2.ensureHK ) && isSubArgs(args1, args2, tp1, tycon2.typeParams)
818+ tryInstantiate(param1, tycon2.ensureLambdaSub ) && isSubArgs(args1, args2, tp1, tycon2.typeParams)
805819 case _ =>
806820 false
807821 }
@@ -1216,8 +1230,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
12161230 if (tp1 eq tp2) tp1
12171231 else if (! tp1.exists) tp2
12181232 else if (! tp2.exists) tp1
1219- else if ((tp1 isRef AnyClass ) || (tp2 isRef NothingClass )) tp2
1220- else if ((tp2 isRef AnyClass ) || (tp1 isRef NothingClass )) tp1
1233+ else if ((tp1 isRef AnyClass ) && ! tp2.isLambdaSub || (tp1 isRef AnyKindClass ) || (tp2 isRef NothingClass )) tp2
1234+ else if ((tp2 isRef AnyClass ) && ! tp1.isLambdaSub || (tp2 isRef AnyKindClass ) || (tp1 isRef NothingClass )) tp1
12211235 else tp2 match { // normalize to disjunctive normal form if possible.
12221236 case OrType (tp21, tp22) =>
12231237 tp1 & tp21 | tp1 & tp22
@@ -1265,8 +1279,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
12651279 if (tp1 eq tp2) tp1
12661280 else if (! tp1.exists) tp1
12671281 else if (! tp2.exists) tp2
1268- else if ((tp1 isRef AnyClass ) || (tp2 isRef NothingClass )) tp1
1269- else if ((tp2 isRef AnyClass ) || (tp1 isRef NothingClass )) tp2
1282+ else if ((tp1 isRef AnyClass ) || (tp1 isRef AnyKindClass ) || ( tp2 isRef NothingClass )) tp1
1283+ else if ((tp2 isRef AnyClass ) || (tp2 isRef AnyKindClass ) || ( tp1 isRef NothingClass )) tp2
12701284 else {
12711285 val t1 = mergeIfSuper(tp1, tp2, canConstrain)
12721286 if (t1.exists) t1
0 commit comments