Skip to content

Commit 5769aa5

Browse files
committed
Never fail a subtype test if atoms don't compare
Singleton types can be aliases of other singleton types (or unions of singletons) in complex ways which atoms don't reflect currently. So to be conservative we should use atoms only for confirming subtype relationships, never for rejecting them.
1 parent 047a449 commit 5769aa5

File tree

2 files changed

+4
-5
lines changed

2 files changed

+4
-5
lines changed

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,8 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
432432
recur(tp1.widenSingletons, tp2)
433433

434434
if (tp2.atoms.nonEmpty && canCompare(tp2.atoms))
435-
tp1.atoms.nonEmpty && tp1.atoms.subsetOf(tp2.atoms)
436-
else
437-
widenOK || joinOK || recur(tp11, tp2) && recur(tp12, tp2)
435+
if (tp1.atoms.nonEmpty && tp1.atoms.subsetOf(tp2.atoms)) return true
436+
widenOK || joinOK || recur(tp11, tp2) && recur(tp12, tp2)
438437
case tp1: MatchType =>
439438
val reduced = tp1.reduced
440439
if (reduced.exists) recur(reduced, tp2) else thirdTry
@@ -600,8 +599,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
600599
compareTypeLambda
601600
case OrType(tp21, tp22) =>
602601
if (tp2.atoms.nonEmpty && canCompare(tp2.atoms))
603-
return tp1.atoms.nonEmpty && tp1.atoms.subsetOf(tp2.atoms) ||
604-
tp1.widen.isRef(NothingClass)
602+
if (tp1.atoms.nonEmpty && tp1.atoms.subsetOf(tp2.atoms)) return true
605603

606604
// The next clause handles a situation like the one encountered in i2745.scala.
607605
// We have:

tests/pos/singlesubtypes.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ object Test {
99
val b: E.b.type = E.b
1010

1111
val c: a.type | b.type = ???
12+
val d: a.type | b.type = c
1213
}

0 commit comments

Comments
 (0)