Skip to content

Commit 9a9de0c

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 8feb596 commit 9a9de0c

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
@@ -245,6 +245,20 @@ object Types {
245245
/** Is this type a (possibly aliased) singleton type? */
246246
def isSingleton(implicit ctx: Context) = dealias.isInstanceOf[SingletonType]
247247

248+
/** Is this type of kind `AnyKind`? */
249+
def hasAnyKind(implicit ctx: Context): Boolean = {
250+
@tailrec def loop(tp: Type): Boolean = tp match {
251+
case tp: TypeRef =>
252+
val sym = tp.symbol
253+
if (sym.isClass) sym == defn.AnyKindClass else loop(tp.superType)
254+
case tp: TypeProxy =>
255+
loop(tp.underlying)
256+
case _ =>
257+
false
258+
}
259+
loop(this)
260+
}
261+
248262
/** Is this type guaranteed not to have `null` as a value? */
249263
final def isNotNull(implicit ctx: Context): Boolean = this match {
250264
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
@@ -661,7 +661,7 @@ trait Checking {
661661

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

0 commit comments

Comments
 (0)