blob: 27a3d21dadc659b70cec5f754a60fa4e236c4c7d (
plain) (
tree)
|
|
trait T[@specialized A] { def apply(a: A): A }
trait TInt extends T[Int]
trait TWithVal { val x: Any = 1; def apply(x: Int): String }
trait TImpure { def apply(x: Int): String ; println(1) }
trait Println { println(1) }
trait TImpureSuper extends Println { def apply(x: Int): String }
object Test extends App {
final val AnonFunClass = "$anonfun$"
final val LMFClass = "$$Lambda$" // LambdaMetaFactory names classes like this
private def LMF(f: Any): Unit = {
val className = f.getClass.toString
assert(!(className contains AnonFunClass), className)
assert((className contains LMFClass), className)
}
private def notLMF(f: Any): Unit = {
val className = f.getClass.toString
assert((className contains AnonFunClass), className)
assert(!(className contains LMFClass), className)
}
// Check that we expand the SAM of a type that is specialized.
// This is an implementation restriction -- the current specialization scheme is not
// amenable to using LambdaMetaFactory to spin up subclasses.
// Since the generic method is abstract, and the specialized ones are concrete,
// specialization is rendered moot because we cannot implement the specialized method
// with the lambda using LMF.
// not LMF if specialized at this type
notLMF((x => x): T[Int])
// not LMF if specialized at this type (via subclass)
notLMF((x => x): TInt)
// LMF ok if not specialized at this type
LMF((x => x): T[String])
// traits with a val member also cannot be instantiated by LMF
val fVal: TWithVal = (x => "a")
notLMF(fVal)
assert(fVal.x == 1)
notLMF((x => "a"): TImpure)
notLMF((x => "a"): TImpureSuper)
}
|