From 63f017586f31de11bc6004dca7cea0c26ceb5ff5 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 29 Mar 2016 16:47:47 -0700 Subject: Better detection of types LMF cannot instantiate. LambdaMetaFactory can only properly instantiate Java interfaces (with one abstract method, of course). A trait always compiles to an interface, but a subclass that can be instantiated may require mixing in further members, which LMF cannot do. (Nested traits, traits with fields,... do not qualify.) Traits that cannot be instantiated by LMF are still SAM targets, we simply created anonymous subclasses as before. --- test/files/run/sammy_restrictions_LMF.scala | 42 ++++++++++++++++++++++ .../run/sammy_specialization_restriction.scala | 34 ------------------ 2 files changed, 42 insertions(+), 34 deletions(-) create mode 100644 test/files/run/sammy_restrictions_LMF.scala delete mode 100644 test/files/run/sammy_specialization_restriction.scala (limited to 'test/files/run') diff --git a/test/files/run/sammy_restrictions_LMF.scala b/test/files/run/sammy_restrictions_LMF.scala new file mode 100644 index 0000000000..40bb234a72 --- /dev/null +++ b/test/files/run/sammy_restrictions_LMF.scala @@ -0,0 +1,42 @@ +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 } + +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) + + +} diff --git a/test/files/run/sammy_specialization_restriction.scala b/test/files/run/sammy_specialization_restriction.scala deleted file mode 100644 index 4487bb3ad7..0000000000 --- a/test/files/run/sammy_specialization_restriction.scala +++ /dev/null @@ -1,34 +0,0 @@ -trait T[@specialized A] { def apply(a: A): A } -trait TInt extends T[Int] - -// 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. -object Test extends App { - final val AnonFunClass = "$anonfun$" - final val LMFClass = "$$Lambda$" // LambdaMetaFactory names classes like this - - def specializedSamPrecludesLMF() = { - val className = ((x => x): T[Int]).getClass.toString - assert((className contains AnonFunClass), className) - assert(!(className contains LMFClass), className) - } - - def specializedSamSubclassPrecludesLMF() = { - val className = ((x => x): TInt).getClass.toString - assert((className contains AnonFunClass), className) - assert(!(className contains LMFClass), className) - } - - def nonSpecializedSamUsesLMF() = { - val className = ((x => x): T[String]).getClass.toString - assert(!(className contains AnonFunClass), className) - assert(className contains LMFClass, className) - } - - specializedSamPrecludesLMF() - nonSpecializedSamUsesLMF() -} -- cgit v1.2.3