Open
Description
Allocations of classes providing extension methods should be eliminated.
Note that this problem is solved in many cases by value classes, for example 1 to 10
expands to Predef.intWrapper(10).to(20)
. After inlining intWrapper
, we get RichInt.MODULE$.to$extension0(1, 10)
.
There are examples where the extension method provider is not a value class, like Ordering.Ops
:
class Ordering[T] {
def lt(x: T, y: T)
class Ops(lhs: T) {
def <(rhs: T) = lt(lhs, rhs)
}
implicit def mkOrderingOps(lhs: T): Ops = new Ops(lhs)
}
object Ordering {
object Implicits {
implicit def infixOrderingOps[T](x: T)(implicit ord: Ordering[T]): Ordering[T]#Ops = new ord.Ops(x)
}
}
There are two ways to make the <
extension method available:
def f[T: Ordering](x: T, y: T) = {
import Ordering.Implicits._
x < y
}
or
def f[T](x: T, y: T)(implicit ev: Ordering[T]) = {
import ev._
x < y
}
In both cases, an Ops
instance is allocated. I haven't checked if we could turn Ops
into a value class.
The https://github.com/typelevel/machinist macro exists for eliminating such allocations.