From 19c945b9d938ed62073d8373c18e7acfef8ab2d7 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 1 Nov 2024 13:35:11 +0000 Subject: [PATCH] Fix provablyDisjoint handling enum constants with mixins --- .../dotty/tools/dotc/core/TypeComparer.scala | 7 ++++--- tests/warn/i21860.scala | 16 ++++++++++++++++ tests/warn/i21860.unenum.scala | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/warn/i21860.scala create mode 100644 tests/warn/i21860.unenum.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 145a038dd856..16637c3286c1 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -3196,9 +3196,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling cls.is(Sealed) && !cls.hasAnonymousChild def decompose(cls: Symbol): List[Symbol] = - cls.children.map { child => - if child.isTerm then child.info.classSymbol - else child + cls.children.flatMap { child => + if child.isTerm then + child.info.classSymbols // allow enum vals to be decomposed to their enum class (then filtered out) and any mixins + else child :: Nil }.filter(child => child.exists && child != cls) def eitherDerivesFromOther(cls1: Symbol, cls2: Symbol): Boolean = diff --git a/tests/warn/i21860.scala b/tests/warn/i21860.scala new file mode 100644 index 000000000000..377d4761e80f --- /dev/null +++ b/tests/warn/i21860.scala @@ -0,0 +1,16 @@ +trait Figure +sealed trait Corners { self: Figure => } + +enum Shape extends Figure: + case Triangle extends Shape with Corners + case Square extends Shape with Corners + case Circle extends Shape + case Ellipsis extends Shape + +def hasCorners(s: Shape): Boolean = s match + case hasCorners: Corners => true // <--- reported as `Unreachable case` + case _ => false + +class Test: + def test(): Unit = + println(hasCorners(Shape.Circle)) diff --git a/tests/warn/i21860.unenum.scala b/tests/warn/i21860.unenum.scala new file mode 100644 index 000000000000..7335e1b6851d --- /dev/null +++ b/tests/warn/i21860.unenum.scala @@ -0,0 +1,17 @@ +trait Figure +sealed trait Corners { self: Figure => } + +sealed abstract class Shape extends Figure +object Shape: + case object Triange extends Shape with Corners + case object Square extends Shape with Corners + case object Circle extends Shape + case object Ellipsis extends Shape + +def hasCorners(s: Shape): Boolean = s match + case hasCorners: Corners => true // <--- reported as `Unreachable case` + case _ => false + +class Test: + def test(): Unit = + println(hasCorners(Shape.Circle))