Skip to content

Commit e2fb56a

Browse files
committed
Fix comparing AnyVal | Null with Null
1 parent 968dd1b commit e2fb56a

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -853,18 +853,23 @@ object Types {
853853
def goAnd(l: Type, r: Type) =
854854
go(l).meet(go(r), pre, safeIntersection = ctx.base.pendingMemberSearches.contains(name))
855855

856-
def goOr(tp: OrType) = tp match {
857-
case OrNull(tp1) if Nullables.unsafeNullsEnabled =>
858-
// Selecting `name` from a type `T | Null` is like selecting `name` from `T`, if
859-
// unsafeNulls is enabled. This can throw at runtime, but we trade soundness for usability.
860-
tp1.findMember(name, pre.stripNull, required, excluded)
861-
case _ =>
856+
def goOr(tp: OrType) =
857+
inline def searchAfterJoin =
862858
// we need to keep the invariant that `pre <: tp`. Branch `union-types-narrow-prefix`
863859
// achieved that by narrowing `pre` to each alternative, but it led to merge errors in
864860
// lots of places. The present strategy is instead of widen `tp` using `join` to be a
865861
// supertype of `pre`.
866862
go(tp.join)
867-
}
863+
864+
if Nullables.unsafeNullsEnabled then tp match
865+
case OrNull(tp1) if tp1 <:< defn.ObjectType =>
866+
// Selecting `name` from a type `T | Null` is like selecting `name` from `T`, if
867+
// unsafeNulls is enabled and T is a subtype of AnyRef.
868+
// This can throw at runtime, but we trade soundness for usability.
869+
tp1.findMember(name, pre.stripNull, required, excluded)
870+
case _ =>
871+
searchAfterJoin
872+
else searchAfterJoin
868873

869874
val recCount = ctx.base.findMemberCount
870875
if (recCount >= Config.LogPendingFindMemberThreshold)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ class Typer extends Namer
626626
val qual = typedExpr(tree.qualifier, shallowSelectionProto(tree.name, pt, this))
627627
val qual1 = if Nullables.unsafeNullsEnabled then
628628
qual.tpe match {
629-
case OrNull(tpe1) =>
629+
case OrNull(tpe1) if tpe1 <:< defn.ObjectType =>
630630
qual.cast(AndType(qual.tpe, tpe1))
631631
case tp =>
632632
if tp.isNullType
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
def test1 =
2+
val v: AnyVal | Null = null
3+
if v == null then
4+
println("null")
5+
6+
def test2 =
7+
val v: Int | Null = 1
8+
if v != null then
9+
println(v)
10+
11+
case class MyVal(val i: Boolean) extends AnyVal
12+
13+
def test3 =
14+
val v: MyVal | Null = MyVal(false)
15+
if v != null then
16+
println(v)

0 commit comments

Comments
 (0)