Skip to content

Fix isNullableClass to also work after Erasure #425

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 26, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 3 additions & 7 deletions src/dotty/tools/dotc/transform/ValueClasses.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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) =
Expand Down
11 changes: 11 additions & 0 deletions tests/pos/nullAsInstanceOf.scala
Original file line number Diff line number Diff line change
@@ -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]
}