Skip to content

Commit 04f6fc3

Browse files
committed
Avoid early widening enum val symbols in provablyDisjointClasses
1 parent 3cd94b4 commit 04f6fc3

File tree

3 files changed

+34
-21
lines changed

3 files changed

+34
-21
lines changed

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

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3201,35 +3201,28 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
32013201
result
32023202
end existsCommonBaseTypeWithDisjointArguments
32033203

3204-
provablyDisjointClasses(cls1, cls2, seen = null)
3204+
provablyDisjointClasses(cls1, cls2)
32053205
|| existsCommonBaseTypeWithDisjointArguments
32063206
end match
32073207
}
32083208

3209-
private def provablyDisjointClasses(cls1: Symbol, cls2: Symbol, seen: util.HashSet[Symbol] | Null)(using Context): Boolean =
3209+
private def provablyDisjointClasses(cls1: Symbol, cls2: Symbol)(using Context): Boolean =
32103210
def isDecomposable(cls: Symbol): Boolean =
3211-
if seen != null && seen.contains(cls) then false
3212-
else cls.is(Sealed) && !cls.hasAnonymousChild
3211+
cls.is(Sealed) && !cls.hasAnonymousChild
32133212

32143213
def decompose(cls: Symbol): List[Symbol] =
3215-
cls.children.flatMap { child =>
3214+
cls.children.map: child =>
32163215
if child.isTerm then
3217-
child.info.classSymbols // allow enum vals to be decomposed to their enum class (then filtered out) and any mixins
3218-
else child :: Nil
3219-
}.filter(child => child.exists && child != cls)
3220-
3221-
inline def seeing(inline cls: Symbol)(inline thunk: util.HashSet[Symbol] => Boolean) =
3222-
val seen1 = if seen == null then new util.HashSet[Symbol] else seen
3223-
try
3224-
seen1 += cls
3225-
thunk(seen1)
3226-
finally seen1 -= cls
3216+
child.info.classSymbol.orElse(child)
3217+
else child
3218+
.filter(child => child.exists && child != cls)
32273219

32283220
def eitherDerivesFromOther(cls1: Symbol, cls2: Symbol): Boolean =
32293221
cls1.derivesFrom(cls2) || cls2.derivesFrom(cls1)
32303222

32313223
def smallestNonTraitBase(cls: Symbol): Symbol =
3232-
cls.asClass.baseClasses.find(!_.is(Trait)).get
3224+
val classes = if cls.isClass then cls.asClass.baseClasses else cls.info.classSymbols
3225+
classes.find(!_.is(Trait)).get
32333226

32343227
if (eitherDerivesFromOther(cls1, cls2))
32353228
false
@@ -3247,11 +3240,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
32473240
// instantiations of `cls1` (terms of the form `new cls1`) are not
32483241
// of type `tp2`. Therefore, we can safely decompose `cls1` using
32493242
// `.children`, even if `cls1` is non abstract.
3250-
seeing(cls1): seen1 =>
3251-
decompose(cls1).forall(x => provablyDisjointClasses(x, cls2, seen1))
3243+
decompose(cls1).forall(x => provablyDisjointClasses(x, cls2))
32523244
else if (isDecomposable(cls2))
3253-
seeing(cls2): seen1 =>
3254-
decompose(cls2).forall(x => provablyDisjointClasses(cls1, x, seen1))
3245+
decompose(cls2).forall(x => provablyDisjointClasses(cls1, x))
32553246
else
32563247
false
32573248
end provablyDisjointClasses

tests/pos/i22266.unenum.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
sealed trait NonPolygon
2+
sealed trait Polygon
3+
4+
sealed trait SymmetryAspect
5+
sealed trait RotationalSymmetry extends SymmetryAspect
6+
sealed trait MaybeRotationalSymmetry extends SymmetryAspect
7+
8+
sealed abstract class Shape
9+
10+
object Shape:
11+
case object Circle extends Shape with NonPolygon with RotationalSymmetry
12+
case object Triangle extends Shape with Polygon with MaybeRotationalSymmetry
13+
case object Square extends Shape with Polygon with RotationalSymmetry
14+
15+
def hasPolygon(
16+
rotationalSyms: Vector[Shape & RotationalSymmetry],
17+
maybeSyms: Vector[Shape & MaybeRotationalSymmetry]
18+
): Boolean =
19+
val all = rotationalSyms.concat(maybeSyms)
20+
all.exists:
21+
case _: Polygon => true
22+
case _ => false

tests/warn/i21860.unenum.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ sealed trait Corners { self: Figure => }
33

44
sealed abstract class Shape extends Figure
55
object Shape:
6-
case object Triange extends Shape with Corners
6+
case object Triangle extends Shape with Corners
77
case object Square extends Shape with Corners
88
case object Circle extends Shape
99
case object Ellipsis extends Shape

0 commit comments

Comments
 (0)