Inline methods and opaque types

This will still compile and throw an exception.
You can use scala.compiletime.error to fail compilation.

1 Like

Yes exactly!
Actually I noticed the problem and already fixed my code, but it was too late to update my post.

package utils

opaque type PositiveInt <: Int = Int

object PositiveInt:
  inline
  def apply(inline n: Int): PositiveInt =
    inline if n == 0
    then compiletime.error("Impossible to build PositiveInt(0)")
    else if n < 0
    then compiletime.error("Impossible to build PositiveInt(-n): negative value.")
    else n

  def make(n: Int): Option[PositiveInt] =
    Option.when(n > 0)(n)

  def apply(n: Int, orByDefault: PositiveInt): PositiveInt =
    make(n).getOrElse(orByDefault)

  extension (inline n: Int)
    inline
    def asPositive: PositiveInt =
      PositiveInt(n)

As a result now you can do:


  // Compiles
  val a = PositiveInt(4)
  val b: Int = a
  val c = 99.asPositive
  val d: Int = c

  // Won't compile
  val e = PositiveInt(0) //Compile-time error: Impossible to build PositiveInt(0)
  val f = -2.asPositive //Compile-time error: Impossible to build PositiveInt(-n): negative value.