How does Unapply work in compiler?


This line corresponds to the code : -

val typedUnapply = UnApply(typedApplied, typedArgsForFormals(args, formals, mode)) setPos tree.pos setType extractedTp

The definition of Unapply can be found here. It is a case class which has a companion object. The companion object extends an Abstract class UnapplyExtractor

object UnApply extends UnApplyExtractor

But it doesn’t implement the abstract functions of UnapplyExtractor. So, how exactly is it working?


I’m going to change the names of the types here, so that you don’t get confused with the class that’s called UnApply and the unapply feature.

Say we have

case class Foo(a: Int, b: String)

object Foo

The compiler automatically generates apply and unapply methods for Foo because it’s a case class. So the generated code looks like

class Foo(val a: Int, val b: String)
object Foo {
  (compiler generated) def apply(a: Int, b: String) = new Foo(a, b)
  (compiler generated) def unapply(foo: Foo) = Option((foo.a, foo.b))

now we have

trait Bar {
  def apply(a: Int, b: String)
  def unapply(foo: Foo): Option[(Int, String)]

object Foo extends Bar

object Foo doesn’t explicitly implement the apply and unapply methods of Bar, but take a look at the compiler generated methods of the Foo object above. They are exactly the methods needed to extend Bar.


you’ll want to ask this sort of question over at


got it. will do that:)