lloydmeta / enumeratum

A type-safe, reflection-free, powerful enumeration implementation for Scala with exhaustive pattern match warnings and helpful integrations.
MIT License
1.18k stars 146 forks source link

Un-sealed abstract class in hierarchy gets ignored on Scala 3.x #377

Open BardurArantsson opened 10 months ago

BardurArantsson commented 10 months ago

Hi,

This is perhaps not a bug, technically, but I found the behavior suprising.

It seems that 'intermediate' abstract classes in a hierarchy must themselves be explicitly marked as sealed for findValues to pick them up.

Here's a little reproducer:

import enumeratum.*

sealed abstract class MyEnum(name: String) extends EnumEntry

object MyEnum extends Enum[MyEnum] {

  abstract class Intermediate(name: String)
    extends MyEnum(name = name)

  case object Foo extends MyEnum("Foo")
  case object Bar extends Intermediate("Bar")

  val values: IndexedSeq[MyEnum] =
    findValues

  @main
  def main(): Unit =
    Console.println(s"values: $values")

}

Will print

values: Vector(Foo)

instead of the expected

values: Vector(Bar, Foo)

Marking the Intermediate abstract class with sealed makes it show up.

Now, technically, the un-sealed abstract class could be extended by code elsewhere (and so all potential subclasses cannot be known), but I found this behavior of simply omitting the Bar very surprising... kind of dangerous because the omission is silent.

Could the macros be changed to include Bar (per the example), or maybe to emit a compiler warning/error about the missing 'sealed'?

lloydmeta commented 10 months ago

I think a warning could make sense. Feel free to submit a PR!