diff --git a/shared/src/main/scala/io/estatico/newtype/NewType.scala b/shared/src/main/scala/io/estatico/newtype/NewType.scala index 736e158..ebadc4c 100644 --- a/shared/src/main/scala/io/estatico/newtype/NewType.scala +++ b/shared/src/main/scala/io/estatico/newtype/NewType.scala @@ -7,6 +7,10 @@ trait NewType extends BaseNewType { self => } object NewType { + class NewTypeUnapplyOps[A](val a: A) extends AnyVal { + def isEmpty: Boolean = false + def get: A = a + } trait Of[R] extends BaseNewType.Of[R] with NewType trait Default[R] extends Of[R] with NewTypeExtras } diff --git a/shared/src/main/scala/io/estatico/newtype/macros/NewTypeMacros.scala b/shared/src/main/scala/io/estatico/newtype/macros/NewTypeMacros.scala index fda5084..a65a0ef 100644 --- a/shared/src/main/scala/io/estatico/newtype/macros/NewTypeMacros.scala +++ b/shared/src/main/scala/io/estatico/newtype/macros/NewTypeMacros.scala @@ -185,14 +185,14 @@ private[macros] class NewTypeMacros(val c: blackbox.Context) clsDef: ClassDef, valDef: ValDef, tparamsNoVar: List[TypeDef], tparamNames: List[TypeName] ): List[Tree] = { if (!unapply) Nil else { - // Note that our unapply method should Some since its isEmpty/get is constant. + // We are using a generic value class name-based extractor not to allocate Some List( if (tparamsNoVar.isEmpty) { - q"""def unapply(x: ${clsDef.name}): Some[${valDef.tpt}] = - Some(x.asInstanceOf[${valDef.tpt}])""" + q"""def unapply(x: ${clsDef.name}): io.estatico.newtype.NewType.NewTypeUnapplyOps[${valDef.tpt}] = + new io.estatico.newtype.NewType.NewTypeUnapplyOps[${valDef.tpt}](x.coerce)""" } else { - q"""def unapply[..$tparamsNoVar](x: ${clsDef.name}[..$tparamNames]): Some[${valDef.tpt}] = - Some(x.asInstanceOf[${valDef.tpt}])""" + q"""def unapply[..$tparamsNoVar](x: ${clsDef.name}[..$tparamNames]): io.estatico.newtype.NewType.NewTypeUnapplyOps[${valDef.tpt}] = + new io.estatico.newtype.NewType.NewTypeUnapplyOps[${valDef.tpt}](x.coerce[${valDef.tpt}])""" } ) } diff --git a/shared/src/test/scala/io/estatico/newtype/macros/NewTypeMacrosTest.scala b/shared/src/test/scala/io/estatico/newtype/macros/NewTypeMacrosTest.scala index 454d5ff..13f2aff 100644 --- a/shared/src/test/scala/io/estatico/newtype/macros/NewTypeMacrosTest.scala +++ b/shared/src/test/scala/io/estatico/newtype/macros/NewTypeMacrosTest.scala @@ -1,5 +1,6 @@ package io.estatico.newtype.macros +import io.estatico.newtype.Coercible import org.scalatest.{FlatSpec, Matchers} import io.estatico.newtype.ops._ import org.scalacheck.Arbitrary