Opaque type's inline method inaccessible inside a trait

102 Views Asked by At

Why inline methods of opaque types can be called from concrete classes but not from traits?

The following code

opaque type ConstrainedBigDecimal = BigDecimal

extension (n: ConstrainedBigDecimal)
    inline def isWhole = n.isWhole

opaque type PositiveBigDecimal <: ConstrainedBigDecimal = BigDecimal
opaque type NegativeBigDecimal <: ConstrainedBigDecimal = BigDecimal

sealed trait Quantity:
    protected type QuantityType <: ConstrainedBigDecimal

    def quantity: QuantityType

    def formatQuantity: String =
        if quantity.isWhole then quantity.toString() else f"$quantity%.2f"

produces

-- Error: test.scala:15:20 --------------------------------------------------------------------------------------------------------------------------
15 |        if quantity.isWhole then quantity.toString() else f"$quantity%.2f"
   |           ^^^^^^^^^^^^^^^^
   |           isWhole cannot be accessed as a member of (n$proxy1 : Quantity.this.QuantityType) from trait Quantity.
   |-------------------------------------------------------------------------------------------------------------------------------------------------
   |Inline stack trace
   |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   |This location contains code that was inlined from test.scala:4
 4 |    inline def isWhole = n.isWhole
   |                         ^^^^^^^^^
    -------------------------------------------------------------------------------------------------------------------------------------------------

However, a concrete class with an identical implementation

case class PositiveQuantity(
    quantity: PositiveBigDecimal
):
    def formatQuantity: String =
        if quantity.isWhole then quantity.toString() else f"$quantity%.2f"

compiles just fine.

0

There are 0 best solutions below