diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 49faeff87ac4..720f0cc4ac55 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -264,9 +264,13 @@ object Types { // If the type is `T | Null` or `T | Nothing`, the class is != Nothing, // and `T` derivesFrom the class, then the OrType derivesFrom the class. // Otherwise, we need to check both sides derivesFrom the class. - if tp.tp1.isBottomType && cls != defn.NothingClass then + def isLowerBottomType(tp: Type) = + tp.isBottomType + && (tp.hasClassSymbol(defn.NothingClass) + || cls != defn.NothingClass && !cls.isValueClass) + if isLowerBottomType(tp.tp1) then loop(tp.tp2) - else if tp.tp2.isBottomType && cls != defn.NothingClass then + else if isLowerBottomType(tp.tp2) then loop(tp.tp1) else loop(tp.tp1) && loop(tp.tp2) diff --git a/tests/neg/null-anyval.scala b/tests/neg/null-anyval.scala new file mode 100644 index 000000000000..82b4b9ad9433 --- /dev/null +++ b/tests/neg/null-anyval.scala @@ -0,0 +1,12 @@ +object Test: + val x: Int = 0 + val y: Int | Null = x // during erasure, x is boxed here, and Int | Null becomes Object + val z0: Int = identity(y) // error + val z1: Int = identity[Int | Null](y) // error + val z2: Int = y // error + + class StrWrapper(x: String) extends AnyVal + val z3: StrWrapper = null // error + val z4: O.T = null // error +object O: + opaque type T = String