Skip to content

Commit fd6054e

Browse files
committed
Clean up kindedness tests
We currently mostly use isLambdaSub which detects unapplied abstract and alias types but not unapplied generic classes. We should use `hasHigherKind` more often, which includes unapplied classes. The first commit fixes a problem with `hasHigherKind` where abstract types upper bounded by `AnyKind` where not classified as higher-kinded. It also changes checkSimpleKinded to use hasHigherKind instead if isLambdaSub.
1 parent 75b66c8 commit fd6054e

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,10 @@ class TypeApplications(val self: Type) extends AnyVal {
212212

213213
/** Is self type of kind != "*"? */
214214
def hasHigherKind(implicit ctx: Context): Boolean =
215-
typeParams.nonEmpty || self.isRef(defn.AnyKindClass)
215+
typeParams.nonEmpty || self.hasAnyKind
216+
217+
/** Is self type of kind "*"? */
218+
def hasFirstKind(implicit ctx: Context): Boolean = !hasHigherKind
216219

217220
/** If self type is higher-kinded, its result type, otherwise NoType.
218221
* Note: The hkResult of an any-kinded type is again AnyKind.

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,20 @@ object Types {
248248
/** Is this type a (possibly aliased) singleton type? */
249249
def isSingleton(implicit ctx: Context) = dealias.isInstanceOf[SingletonType]
250250

251+
/** Is this type of kind `AnyKind`? */
252+
def hasAnyKind(implicit ctx: Context): Boolean = {
253+
@tailrec def loop(tp: Type): Boolean = tp match {
254+
case tp: TypeRef =>
255+
val sym = tp.symbol
256+
if (sym.isClass) sym == defn.AnyKindClass else loop(tp.superType)
257+
case tp: TypeProxy =>
258+
loop(tp.underlying)
259+
case _ =>
260+
false
261+
}
262+
loop(this)
263+
}
264+
251265
/** Is this type guaranteed not to have `null` as a value? */
252266
final def isNotNull(implicit ctx: Context): Boolean = this match {
253267
case tp: ConstantType => tp.value.value != null

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ trait Checking {
704704

705705
/** Check that `tpt` does not define a higher-kinded type */
706706
def checkSimpleKinded(tpt: Tree)(implicit ctx: Context): Tree =
707-
if (tpt.tpe.isLambdaSub && !ctx.compilationUnit.isJava) {
707+
if (tpt.tpe.hasHigherKind && !ctx.compilationUnit.isJava) {
708708
// be more lenient with missing type params in Java,
709709
// needed to make pos/java-interop/t1196 work.
710710
errorTree(tpt, MissingTypeParameterFor(tpt.tpe))

0 commit comments

Comments
 (0)