Skip to content

Commit

Permalink
Make reference types nullable again after erasure
Browse files Browse the repository at this point in the history
Before erasure, reference types are non-nullable, but after it they
should be nullable again, because JVM types are nullable.

This fixes tests/pos/i536 by changing the notion of a nullable type to
take into consideration the current phase id.

A similar thing is already done in TypeComparer in a different case:
https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/TypeComparer.scala#L676
  • Loading branch information
abeln committed Dec 7, 2018
1 parent f6e5187 commit e9b50e7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 6 deletions.
12 changes: 10 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -967,8 +967,16 @@ class Definitions {
name.length > prefix.length &&
name.drop(prefix.length).forall(_.isDigit))

def isBottomClass(cls: Symbol) = cls == NothingClass
def isBottomType(tp: Type) = tp.derivesFrom(NothingClass)
def isBottomClass(cls: Symbol) = {
// After erasure, reference types become nullable again.
if (ctx.phaseId <= ctx.erasurePhase.id) cls == NothingClass
else cls == NothingClass || cls == NullClass
}
def isBottomType(tp: Type) = {
// After erasure, reference types become nullable again.
if (ctx.phaseId <= ctx.erasurePhase.id) tp.derivesFrom(NothingClass)
else tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)
}

/** Is a function class.
* - FunctionN for N >= 0
Expand Down
8 changes: 6 additions & 2 deletions compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -681,8 +681,12 @@ object SymDenotations {
}

/** Is this symbol a class with nullable values? */
final def isNullableClass(implicit ctx: Context): Boolean =
symbol == defn.NullClass || symbol == defn.AnyRefAlias || symbol == defn.AnyClass
final def isNullableClass(implicit ctx: Context): Boolean = {
// After erasure, reference types become nullable again.
if (ctx.phaseId <= ctx.erasurePhase.id) symbol == defn.NullClass || symbol == defn.AnyRefAlias || symbol == defn.AnyClass
else isClass && !isValueClass && !is(ModuleClass) && symbol != defn.NothingClass
}


/** 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
4 changes: 2 additions & 2 deletions tests/pos/i536.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ trait Comp[T]
trait Coll[T]
class C extends Comp[C]
object Max {
def max[M <: Comp[_ >: M]](x: Coll[_ <: M] | Null): M = ???
def max[M <: Comp[_ >: M]](x: Coll[_ <: M]): M = ???
def max[M](x: Coll[_ <: M], cmp: Object): M = ???
val xs: Coll[C] = ???
val m1 = max(xs)
val m2 = max(null)
val m2 = max(???)

java.util.Collections.max(null)
}

0 comments on commit e9b50e7

Please sign in to comment.