Skip to content

Commit d50da57

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 74376f3 commit d50da57

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

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

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

2510-
/** Can we enumerate all instantiations of this type? */
2511-
def isClosedSum(tp: Symbol): Boolean =
2512-
tp.is(Sealed) && tp.isOneOf(AbstractOrTrait) && !tp.hasAnonymousChild
2513-
25142510
/** Splits a closed type into a disjunction of smaller types.
25152511
* It should hold that `tp` and `decompose(tp).reduce(_ or _)`
25162512
* denote the same set of values.
@@ -2551,9 +2547,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25512547
// subtype, so they must be unrelated by single inheritance
25522548
// of classes.
25532549
true
2554-
else if (isClosedSum(cls1))
2550+
else if (cls1.isClosedSum)
25552551
decompose(cls1, tp1).forall(x => provablyDisjoint(x, tp2))
2556-
else if (isClosedSum(cls2))
2552+
else if (cls1.isClosedSum)
25572553
decompose(cls2, tp2).forall(x => provablyDisjoint(x, tp1))
25582554
else
25592555
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/pos/i11686-ordinal.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// scalac: -Werror
2+
// From https://github.com/lampepfl/dotty/pull/11686#pullrequestreview-677440250
3+
4+
sealed trait Top
5+
object Top
6+
7+
final case class MiddleA() extends Top with Bottom
8+
final case class MiddleB() extends Top with Bottom
9+
final case class MiddleC() extends Top with Bottom
10+
11+
sealed trait Bottom extends Top

0 commit comments

Comments
 (0)