Skip to content

Commit c5d8cba

Browse files
committed
Merge pull request #425 from smarter/fix/isNullableClass
Fix isNullableClass to also work after Erasure
2 parents ed1de3a + d058f98 commit c5d8cba

File tree

3 files changed

+23
-11
lines changed

3 files changed

+23
-11
lines changed

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -496,13 +496,18 @@ object SymDenotations {
496496
*/
497497
def derivesFrom(base: Symbol)(implicit ctx: Context) = false
498498

499-
/** Is this symbol a class that does not extend `AnyVal`? */
500-
final def isNonValueClass(implicit ctx: Context): Boolean =
501-
isClass && !derivesFrom(defn.AnyValClass) && (symbol ne defn.NothingClass)
499+
/** Is this symbol a class that extends `AnyVal`? */
500+
final def isValueClass(implicit ctx: Context): Boolean = {
501+
val di = this.initial.asSymDenotation
502+
di.isClass &&
503+
di.derivesFrom(defn.AnyValClass)(ctx.withPhase(di.validFor.firstPhaseId))
504+
// We call derivesFrom at the initial phase both because AnyVal does not exist
505+
// after Erasure and to avoid cyclic references caused by forcing denotations
506+
}
502507

503508
/** Is this symbol a class references to which that are supertypes of null? */
504509
final def isNullableClass(implicit ctx: Context): Boolean =
505-
isNonValueClass && !(this is ModuleClass)
510+
isClass && !isValueClass && !(this is ModuleClass)
506511

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

src/dotty/tools/dotc/transform/ValueClasses.scala

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,9 @@ import Flags._
1212
object ValueClasses {
1313

1414
def isDerivedValueClass(d: SymDenotation)(implicit ctx: Context) = {
15-
val di = d.initial.asSymDenotation
16-
di.isClass &&
17-
di.derivesFrom(defn.AnyValClass)(ctx.withPhase(di.validFor.firstPhaseId)) &&
18-
// need to check derivesFrom at initialPhase to avoid cyclic references caused
19-
// by forcing in transformInfo
20-
(di.symbol ne defn.AnyValClass) &&
21-
!di.isPrimitiveValueClass
15+
d.isValueClass &&
16+
(d.initial.symbol ne defn.AnyValClass) && // Compare the initial symbol because AnyVal does not exist after erasure
17+
!d.isPrimitiveValueClass
2218
}
2319

2420
def isMethodWithExtension(d: SymDenotation)(implicit ctx: Context) =

tests/pos/nullAsInstanceOf.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
object Test {
2+
val b = null.asInstanceOf[Byte]
3+
val c = null.asInstanceOf[Char]
4+
val s = null.asInstanceOf[Short]
5+
val i = null.asInstanceOf[Int]
6+
val l = null.asInstanceOf[Long]
7+
val f = null.asInstanceOf[Float]
8+
val d = null.asInstanceOf[Double]
9+
10+
val str = null.asInstanceOf[String]
11+
}

0 commit comments

Comments
 (0)