diff options
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ValueClasses.scala | 10 | ||||
-rw-r--r-- | tests/pos/nullAsInstanceOf.scala | 11 |
3 files changed, 23 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 44629c036..62e9ab0d2 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -496,13 +496,18 @@ object SymDenotations { */ def derivesFrom(base: Symbol)(implicit ctx: Context) = false - /** Is this symbol a class that does not extend `AnyVal`? */ - final def isNonValueClass(implicit ctx: Context): Boolean = - isClass && !derivesFrom(defn.AnyValClass) && (symbol ne defn.NothingClass) + /** Is this symbol a class that extends `AnyVal`? */ + final def isValueClass(implicit ctx: Context): Boolean = { + val di = this.initial.asSymDenotation + di.isClass && + di.derivesFrom(defn.AnyValClass)(ctx.withPhase(di.validFor.firstPhaseId)) + // We call derivesFrom at the initial phase both because AnyVal does not exist + // after Erasure and to avoid cyclic references caused by forcing denotations + } /** Is this symbol a class references to which that are supertypes of null? */ final def isNullableClass(implicit ctx: Context): Boolean = - isNonValueClass && !(this is ModuleClass) + isClass && !isValueClass && !(this is ModuleClass) /** Is this definition accessible as a member of tree with type `pre`? * @param pre The type of the tree from which the selection is made diff --git a/src/dotty/tools/dotc/transform/ValueClasses.scala b/src/dotty/tools/dotc/transform/ValueClasses.scala index 276385b0b..ab4bba94e 100644 --- a/src/dotty/tools/dotc/transform/ValueClasses.scala +++ b/src/dotty/tools/dotc/transform/ValueClasses.scala @@ -12,13 +12,9 @@ import Flags._ object ValueClasses { def isDerivedValueClass(d: SymDenotation)(implicit ctx: Context) = { - val di = d.initial.asSymDenotation - di.isClass && - di.derivesFrom(defn.AnyValClass)(ctx.withPhase(di.validFor.firstPhaseId)) && - // need to check derivesFrom at initialPhase to avoid cyclic references caused - // by forcing in transformInfo - (di.symbol ne defn.AnyValClass) && - !di.isPrimitiveValueClass + d.isValueClass && + (d.initial.symbol ne defn.AnyValClass) && // Compare the initial symbol because AnyVal does not exist after erasure + !d.isPrimitiveValueClass } def isMethodWithExtension(d: SymDenotation)(implicit ctx: Context) = diff --git a/tests/pos/nullAsInstanceOf.scala b/tests/pos/nullAsInstanceOf.scala new file mode 100644 index 000000000..2662df72e --- /dev/null +++ b/tests/pos/nullAsInstanceOf.scala @@ -0,0 +1,11 @@ +object Test { + val b = null.asInstanceOf[Byte] + val c = null.asInstanceOf[Char] + val s = null.asInstanceOf[Short] + val i = null.asInstanceOf[Int] + val l = null.asInstanceOf[Long] + val f = null.asInstanceOf[Float] + val d = null.asInstanceOf[Double] + + val str = null.asInstanceOf[String] +} |