How to inline an enum properly?

Lately, i tried to inline an enum so to eliminate some code at compile time. But i was not able to achieve my goal. What am i missing here and how to do it properly?

My first naive attempt:

import scala.math.Ordered.orderingToOrdered

object Test :
  enum Level :
    case One, Two

  object Level :
    given Ordering[Level] = Ordering.Int.on(_.ordinal)

  inline def compare(inline level: Level): String = inline if level < Level.Two then "Yes" else "No"

inline val myValue = Test.Level.One 
val compared = Test.compare(myValue)

gives the warning:

Cannot reduce `inline if` because its condition is not a constant value: scala.math.Ordered.orderingToOrdered[Playground.Test.Level](Playground.myValue)(
  Playground.Test.Level.given_Ordering_Level).<(Playground.Test.Level.Two) 

Okay, so maybe i should use a little less trickery here, second attempt:

object Test :
  enum Level :
    case One, Two

  inline def compare(inline level: Level): String = inline if level.ordinal < Level.Two.ordinal then "Yes" else "No"

inline val myValue = Test.Level.One 
val compared = Test.compare(myValue)

Hmm, essentially the same warning here:

Cannot reduce `inline if` because its condition is not a constant value: Playground.myValue.ordinal.<(Playground.Test.Level.Two.ordinal)

most likely ordinal cannot be inlined because its not defined inline .

New idea, which is not so scaleable for many enums, but lets try:

object Test :
  enum Level :
    case One, Two

  object Level :
    inline def catchCompare(inline a: Level, inline b: Level): Int = 
      inline (a,b) match 
        case (Level.One, Level.One) => 0
        case (Level.One, Level.Two) => -1
        case (Level.Two, Level.One) => 1
        case (Level.Two, Level.Two) => 0

  inline def compare(inline level: Level): String = inline if Level.catchCompare(level,Level.Two) < 0 then "Yes" else "No"

inline val myValue = Test.Level.One 
val compared = Test.compare(myValue)

The warning now is a little longer, but essentially the same. I even tried to do it with writing out all inline if explicitly, without success. How should this be done?

1 Like

There is similar ticket that even Java enums are no longer constants in Scala, so they can’t be args to Java annotations.

I haven’t tried your example, but inline transparent means inline at typer, so it might help.

2 Likes

Thanks for the tip, i tried it … no difference. Is it possible at all, to use enums in such inline constructions? Would be a pity if not. Anyway … we always have the good old extending a sealed trait solution. That works!