Skip to content

Commit 15ad362

Browse files
committed
Generalize bottom type test in TypeComparer
Also treat TermRefs with Nothing types as bottom types. In i9717/Test.scala we got a redundant cast `js.native.$asInstanceOf$[A with B]` because a nottom test did not trigger. The crash due to that cast has been fixed, but it's still better to avoid the cast altogether.
1 parent 6cd0a10 commit 15ad362

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
112112
true
113113
}
114114

115+
private def isBottom(tp: Type) = tp.widen.isRef(NothingClass)
116+
115117
protected def gadtBounds(sym: Symbol)(using Context) = ctx.gadt.bounds(sym)
116118
protected def gadtAddLowerBound(sym: Symbol, b: Type): Boolean = ctx.gadt.addBound(sym, b, isUpper = false)
117119
protected def gadtAddUpperBound(sym: Symbol, b: Type): Boolean = ctx.gadt.addBound(sym, b, isUpper = true)
@@ -371,7 +373,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
371373
thirdTry
372374
case tp1: TypeParamRef =>
373375
def flagNothingBound = {
374-
if (!frozenConstraint && tp2.isRef(NothingClass) && state.isGlobalCommittable) {
376+
if (!frozenConstraint && isBottom(tp2) && state.isGlobalCommittable) {
375377
def msg = s"!!! instantiated to Nothing: $tp1, constraint = ${constraint.show}"
376378
if (Config.failOnInstantiationToNothing) assert(false, msg)
377379
else report.log(msg)
@@ -479,7 +481,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
479481
case _ => false
480482
}) ||
481483
narrowGADTBounds(tp2, tp1, approx, isUpper = false)) &&
482-
{ tp1.isRef(NothingClass) || GADTusage(tp2.symbol) }
484+
{ isBottom(tp1) || GADTusage(tp2.symbol) }
483485
}
484486
isSubApproxHi(tp1, info2.lo) || compareGADT || tryLiftedToThis2 || fourthTry
485487

@@ -488,7 +490,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
488490
if (cls2.isClass)
489491
if (cls2.typeParams.isEmpty) {
490492
if (cls2 eq AnyKindClass) return true
491-
if (tp1.isRef(NothingClass)) return true
493+
if (isBottom(tp1)) return true
492494
if (tp1.isLambdaSub) return false
493495
// Note: We would like to replace this by `if (tp1.hasHigherKind)`
494496
// but right now we cannot since some parts of the standard library rely on the
@@ -1872,8 +1874,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
18721874
if (tp1 eq tp2) tp1
18731875
else if (!tp1.exists) tp2
18741876
else if (!tp2.exists) tp1
1875-
else if tp1.isAny && !tp2.isLambdaSub || tp1.isAnyKind || tp2.isRef(NothingClass) then tp2
1876-
else if tp2.isAny && !tp1.isLambdaSub || tp2.isAnyKind || tp1.isRef(NothingClass) then tp1
1877+
else if tp1.isAny && !tp2.isLambdaSub || tp1.isAnyKind || isBottom(tp2) then tp2
1878+
else if tp2.isAny && !tp1.isLambdaSub || tp2.isAnyKind || isBottom(tp1) then tp1
18771879
else tp2 match { // normalize to disjunctive normal form if possible.
18781880
case tp2: LazyRef =>
18791881
glb(tp1, tp2.ref)
@@ -1925,8 +1927,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
19251927
if (tp1 eq tp2) tp1
19261928
else if (!tp1.exists) tp1
19271929
else if (!tp2.exists) tp2
1928-
else if tp1.isAny && !tp2.isLambdaSub || tp1.isAnyKind || tp2.isRef(NothingClass) then tp1
1929-
else if tp2.isAny && !tp1.isLambdaSub || tp2.isAnyKind || tp1.isRef(NothingClass) then tp2
1930+
else if tp1.isAny && !tp2.isLambdaSub || tp1.isAnyKind || isBottom(tp2) then tp1
1931+
else if tp2.isAny && !tp1.isLambdaSub || tp2.isAnyKind || isBottom(tp1) then tp2
19301932
else
19311933
def mergedLub(tp1: Type, tp2: Type): Type = {
19321934
tp1.atoms match

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ object Types {
268268
case _ => false
269269
}
270270

271-
/** Is this type exactly Any (no vars, aliases, refinements etc allowed)? */
271+
/** Is this type exactly Any (no vars, aliases, refinements etc allowed)? */
272272
def isTopType(using Context): Boolean = this match {
273273
case tp: TypeRef =>
274274
tp.name == tpnme.Any && (tp.symbol eq defn.AnyClass)

0 commit comments

Comments
 (0)