Skip to content

Commit 69870ce

Browse files
committed
ordinal: drop unchecked with sealed abstract skips
In the `ordinal` method, drop the use of `@unchecked` by skipping children that are sealed traits or sealed abstract classes and don't have any anonymous subclasses. The `@unchecked` I added in ee5a82f. In a PR to specifically with reachability I started similar warnings in `ordinal` (this was before adding `@unchecked` was merged) so I'm hoping with this patch to avoid the false positives properly.
1 parent 6a3cd1f commit 69870ce

File tree

4 files changed

+17
-11
lines changed

4 files changed

+17
-11
lines changed

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2526,10 +2526,6 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25262526
case _ => false
25272527
})
25282528

2529-
/** Can we enumerate all instantiations of this type? */
2530-
def isClosedSum(tp: Symbol): Boolean =
2531-
tp.is(Sealed) && tp.isOneOf(AbstractOrTrait) && !tp.hasAnonymousChild
2532-
25332529
/** Splits a closed type into a disjunction of smaller types.
25342530
* It should hold that `tp` and `decompose(tp).reduce(_ or _)`
25352531
* denote the same set of values.
@@ -2570,9 +2566,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25702566
// subtype, so they must be unrelated by single inheritance
25712567
// of classes.
25722568
true
2573-
else if (isClosedSum(cls1))
2569+
else if (cls1.isClosedSum)
25742570
decompose(cls1, tp1).forall(x => provablyDisjoint(x, tp2))
2575-
else if (isClosedSum(cls2))
2571+
else if (cls2.isClosedSum)
25762572
decompose(cls2, tp2).forall(x => provablyDisjoint(x, tp1))
25772573
else
25782574
false

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ object SymUtils:
246246
def hasAnonymousChild(using Context): Boolean =
247247
self.children.exists(_ `eq` self)
248248

249+
/** Can we enumerate all instantiations of this type? */
250+
def isClosedSum(using Context): Boolean =
251+
self.is(Sealed) && self.isOneOf(AbstractOrTrait) && !self.hasAnonymousChild
252+
249253
/** Is this symbol directly owner by a term symbol, i.e., is it local to a block? */
250254
def isLocalToBlock(using Context): Boolean =
251255
self.owner.isTerm

compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,13 +517,19 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
517517
def ordinalBody(cls: Symbol, param: Tree)(using Context): Tree =
518518
if (cls.is(Enum)) param.select(nme.ordinal).ensureApplied
519519
else {
520+
def collect(children: List[Symbol], seen: Set[Symbol], acc: List[Symbol]): List[Symbol] = children match {
521+
case c :: rest if seen(c) => collect(rest, seen, acc)
522+
case c :: rest if c.isClosedSum => collect(c.children ::: rest, seen + c, acc)
523+
case c :: rest => collect(rest, seen + c, c :: acc)
524+
case _ => acc
525+
}
520526
val cases =
521-
for ((child, idx) <- cls.children.zipWithIndex) yield {
527+
for ((child, idx) <- collect(List(cls), Set(), Nil).reverseIterator.zipWithIndex) yield {
522528
val patType = if (child.isTerm) child.reachableTermRef else child.reachableRawTypeRef
523-
val pat = Typed(untpd.Ident(nme.WILDCARD).withType(patType), TypeTree(patType))
529+
val pat = Typed(Underscore(patType), TypeTree(patType))
524530
CaseDef(pat, EmptyTree, Literal(Constant(idx)))
525531
}
526-
Match(param.annotated(New(defn.UncheckedAnnot.typeRef, Nil)), cases)
532+
Match(param, cases.toList)
527533
}
528534

529535
/** - If `impl` is the companion of a generic sum, add `deriving.Mirror.Sum` parent

tests/run-custom-args/fatal-warnings/i11050.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ object Test:
7979
val d = D()
8080
val e = E()
8181

82-
assertEq(List(d, e).map(m.ordinal), List(0, 0))
82+
assertEq(List(d, e).map(m.ordinal), List(0, 1))
8383
assertShow[A](d, "[0] [0] D")
84-
assertShow[A](e, "[0] [1] E")
84+
assertShow[A](e, "[1] [1] E")
8585
end testFromAkkaCB
8686

8787
def testFromAkkaCB2() =

0 commit comments

Comments
 (0)