Skip to content

Commit e5f50ec

Browse files
committed
Shortcircuit slow path typing Nothing <:< XYZ for non phantoms.
1 parent 9128816 commit e5f50ec

File tree

3 files changed

+27
-9
lines changed

3 files changed

+27
-9
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -652,8 +652,10 @@ object SymDenotations {
652652
}
653653

654654
/** Is this symbol a class references to which that are supertypes of null? */
655-
final def isNullableClass(implicit ctx: Context): Boolean =
656-
isClass && !isValueClass && !(this is ModuleClass) && symbol != defn.NothingClass
655+
final def isNullableClass(implicit ctx: Context): Boolean = {
656+
isClass && !isValueClass && !(this is ModuleClass) &&
657+
symbol != defn.NothingClass && symbol != defn.PhantomAny && symbol != defn.PhantomNothing
658+
}
657659

658660
/** Is this definition accessible as a member of tree with type `pre`?
659661
* @param pre The type of the tree from which the selection is made

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

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
4848
private var myAnyClass: ClassSymbol = null
4949
private var myNothingClass: ClassSymbol = null
5050
private var myNullClass: ClassSymbol = null
51+
private var myPhantomAnyClass: ClassSymbol = null
5152
private var myPhantomNothingClass: ClassSymbol = null
5253
private var myObjectClass: ClassSymbol = null
5354
private var myAnyType: TypeRef = null
@@ -65,7 +66,11 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
6566
if (myNullClass == null) myNullClass = defn.NullClass
6667
myNullClass
6768
}
68-
def PhantomNothing = {
69+
def PhantomAnyClass = {
70+
if (myPhantomAnyClass == null) myPhantomAnyClass = defn.PhantomAny
71+
myPhantomAnyClass
72+
}
73+
def PhantomNothingClass = {
6974
if (myPhantomNothingClass == null) myPhantomNothingClass = defn.PhantomNothing
7075
myPhantomNothingClass
7176
}
@@ -556,10 +561,16 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
556561
case OrType(tp1, tp2) => isNullable(tp1) || isNullable(tp2)
557562
case _ => false
558563
}
559-
if (tp1.symbol eq NothingClass) tp2.isValueTypeOrLambda && (tp2.topType.classSymbol eq AnyClass)
560-
else if (tp1.symbol eq NullClass) isNullable(tp2) && (tp2.topType.classSymbol eq AnyClass)
561-
else if (tp1.symbol eq PhantomNothing) tp2.isValueTypeOrLambda && (tp1.topType == tp2.topType)
562-
else false
564+
def isPhantom(tp: Type): Boolean = {
565+
// note that the only phantom classes are PhantomAnyClass and PhantomNothingClass
566+
val sym = tp.typeSymbol
567+
(sym eq PhantomAnyClass) || (sym eq PhantomNothingClass) ||
568+
(!sym.isClass && (tp.topType.classSymbol eq PhantomAnyClass))
569+
}
570+
val sym1 = tp1.symbol
571+
(sym1 eq NothingClass) && tp2.isValueTypeOrLambda && !isPhantom(tp2) ||
572+
(sym1 eq NullClass) && isNullable(tp2) ||
573+
(sym1 eq PhantomNothingClass) && tp1.topType == tp2.topType
563574
}
564575
case tp1: SingletonType =>
565576
/** if `tp2 == p.type` and `p: q.type` then try `tp1 <:< q.type` as a last effort.*/

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,12 @@ object Types {
176176
}
177177

178178
/** Is phantom if upper bounded by XYZ.Any where XYZ extends scala.Phantom */
179-
final def isPhantom(implicit ctx: Context): Boolean = isPhantomClass(topType.classSymbol)
179+
final def isPhantom(implicit ctx: Context): Boolean = {
180+
// note that the only phantom classes are PhantomAnyClass and PhantomNothingClass
181+
val sym = typeSymbol
182+
(sym eq defn.PhantomAny) || (sym eq defn.PhantomNothing) ||
183+
(!sym.isClass && (topType.classSymbol eq defn.PhantomAny))
184+
}
180185

181186
/** Returns the top type of the lattice
182187
* - XYX.Any if XYZ extends scala.Phantom and this type is upper bounded XYZ.Any
@@ -201,7 +206,7 @@ object Types {
201206

202207
/** If the symbol is of the class scala.Phantom.Any or scala.Phantom.Nothing */
203208
private def isPhantomClass(sym: Symbol)(implicit ctx: Context): Boolean =
204-
sym.isClass && (sym.owner eq defn.PhantomClass)
209+
(sym eq defn.PhantomAny) || (sym eq defn.PhantomNothing)
205210

206211
/** Is this type guaranteed not to have `null` as a value?
207212
* For the moment this is only true for modules, but it could

0 commit comments

Comments
 (0)