Skip to content

Eliminate allocations of extension method providers #73

Open
@lrytz

Description

@lrytz

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions