Skip to content

Commit e8eb6d9

Browse files
committed
Fix isInstanceOfEvaluator
We had: scala> null.isInstanceOf[String] -- Warning: <console>:5:17 ----------------------------------------------------- 5 |null.isInstanceOf[String] |^^^^^^^^^^^^^^^^^^^^^^^^^ |this will always yield true if the scrutinee is non-null, since `Null` is a subclass of `String` (will be optimized away) val res0: Boolean = true scala> val x: AnyRef = null val x: AnyRef = null scala> x.isInstanceOf[String] val res1: Boolean = false Fixed by using `isNullable`.
1 parent 6fd3971 commit e8eb6d9

File tree

3 files changed

+10
-5
lines changed

3 files changed

+10
-5
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
777777
else Erasure.Boxing.adaptToType(tree, tp)
778778

779779
/** `tree ne null` (might need a cast to be type correct) */
780-
def testNotNull(implicit ctx: Context): Tree =
780+
def testNotNull(implicit ctx: Context): Tree =
781781
tree.ensureConforms(defn.ObjectType)
782782
.select(defn.Object_ne).appliedTo(Literal(Constant(null)))
783783

compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,15 @@ class IsInstanceOfEvaluator extends MiniPhaseTransform { thisTransformer =>
9090
* If `to` is set to true and the qualifier is not a primitive, the
9191
* instanceOf is replaced by a null check, since:
9292
*
93-
* `scrutinee.isInstanceOf[Selector]` if `scrutinee eq null`
93+
* `scutinee == null` implies `!scrutinee.isInstanceOf[Selector]`
9494
*/
9595
def rewrite(qualifier: Tree, to: Boolean): Tree =
96-
if (!to || !qualifier.tpe.widen.derivesFrom(defn.AnyRefAlias)) {
96+
if (to && !qualifier.tpe.isNotNull) qualifier.testNotNull
97+
else {
9798
val literal = Literal(Constant(to))
9899
if (!isPureExpr(qualifier)) Block(List(qualifier), literal)
99100
else literal
100-
} else
101-
Apply(qualifier.select(defn.Object_ne), List(Literal(Constant(null))))
101+
}
102102

103103
/** Attempts to rewrite type test to either `scrutinee ne null` or a
104104
* constant. Any_typeTest nodes have been rewritten to Any_isInstanceOf at this point.

tests/run/nullInstanceEval.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test extends App {
2+
val x = null
3+
assert(!x.isInstanceOf[String])
4+
assert(!(x: AnyRef).isInstanceOf[String])
5+
}

0 commit comments

Comments
 (0)