diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/files/neg/sammy_restrictions.check | 5 | ||||
-rw-r--r-- | test/files/neg/sammy_restrictions.scala | 2 | ||||
-rw-r--r-- | test/files/pos/sammy_implicit.scala | 2 | ||||
-rw-r--r-- | test/files/pos/sammy_poly.scala | 3 | ||||
-rw-r--r-- | test/files/run/indylambda-boxing/test.scala | 7 | ||||
-rw-r--r-- | test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala | 29 |
6 files changed, 33 insertions, 15 deletions
diff --git a/test/files/neg/sammy_restrictions.check b/test/files/neg/sammy_restrictions.check index 8cc49f9aa9..0276f3a067 100644 --- a/test/files/neg/sammy_restrictions.check +++ b/test/files/neg/sammy_restrictions.check @@ -8,9 +8,6 @@ sammy_restrictions.scala:32: error: type mismatch; required: TwoAbstract ((x: Int) => 0): TwoAbstract ^ -sammy_restrictions.scala:34: error: class type required but DerivedOneAbstract with OneAbstract found - ((x: Int) => 0): NonClassType // "class type required". I think we should avoid SAM translation here. - ^ sammy_restrictions.scala:35: error: type mismatch; found : Int => Int required: NoEmptyConstructor @@ -46,4 +43,4 @@ sammy_restrictions.scala:44: error: type mismatch; required: PolyMethod ((x: Int) => 0): PolyMethod ^ -10 errors found +9 errors found diff --git a/test/files/neg/sammy_restrictions.scala b/test/files/neg/sammy_restrictions.scala index d003cfaf36..101342ad0b 100644 --- a/test/files/neg/sammy_restrictions.scala +++ b/test/files/neg/sammy_restrictions.scala @@ -31,7 +31,7 @@ object Test { (() => 0) : NoAbstract ((x: Int) => 0): TwoAbstract ((x: Int) => 0): DerivedOneAbstract // okay - ((x: Int) => 0): NonClassType // "class type required". I think we should avoid SAM translation here. + ((x: Int) => 0): NonClassType // okay -- we also allow type aliases in instantiation expressions, if they resolve to a class type ((x: Int) => 0): NoEmptyConstructor ((x: Int) => 0): OneEmptyConstructor // okay ((x: Int) => 0): OneEmptySecondaryConstructor // derived class must have an empty *primary* to call. diff --git a/test/files/pos/sammy_implicit.scala b/test/files/pos/sammy_implicit.scala index c9c2519bab..e4b82df4cc 100644 --- a/test/files/pos/sammy_implicit.scala +++ b/test/files/pos/sammy_implicit.scala @@ -6,5 +6,5 @@ abstract class SamImplicitConvert { implicit def conv(xs: Array[Int]): Lst[Int] - val encoded = flatMap (_.getBytes) + def encoded = flatMap (_.getBytes) } diff --git a/test/files/pos/sammy_poly.scala b/test/files/pos/sammy_poly.scala index c629be7166..75ee36f654 100644 --- a/test/files/pos/sammy_poly.scala +++ b/test/files/pos/sammy_poly.scala @@ -1,7 +1,8 @@ // test synthesizeSAMFunction where the sam type is not fully defined class T { trait F[T, U] { def apply(x: T): U } +// type F[T, U] = T => U // NOTE: the f(x) desugaring for now assumes the single abstract method is called 'apply' def app[T, U](x: T)(f: F[T, U]): U = f(x) app(1)(x => List(x)) -}
\ No newline at end of file +} diff --git a/test/files/run/indylambda-boxing/test.scala b/test/files/run/indylambda-boxing/test.scala index cc0a460640..82f8d2f497 100644 --- a/test/files/run/indylambda-boxing/test.scala +++ b/test/files/run/indylambda-boxing/test.scala @@ -2,15 +2,16 @@ class Capture class Test { def test1 = (i: Int) => "" def test2 = (i: VC) => i - def test3 = (i: Int) => i + def test3 = (i: Int) => i // not adapted, specialized - def test4 = {val c = new Capture; (i: Int) => {(c, Test.this.toString); 42} } + def test4 = {val c = new Capture; (i: Int) => {(c, Test.this.toString); 42} } // not adapted, specialized def test5 = {val c = new Capture; (i: VC) => (c, Test.this.toString) } def test6 = {val c = new Capture; (i: Int) => (c, Test.this.toString) } def test7 = {val vc = new Capture; (i: Int) => vc } - def test8 = {val c = 42; (s: String) => (s, c)} + def test8 = {val c = 42; (s: String) => (s, c)} // not adapted def test9 = {val c = 42; (s: String) => ()} + def test10 = {(s: List[String]) => ()} } object Test { diff --git a/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala b/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala index 758566fe53..d29f6b0a13 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala @@ -31,25 +31,44 @@ class IndyLambdaTest extends ClearAfterClass { case _ => Nil }.head } + + val obj = "Ljava/lang/Object;" + val str = "Ljava/lang/String;" + // unspecialized functions that have a primitive in parameter or return position // give rise to a "boxing bridge" method (which has the suffix `$adapted`). // This is because Scala's unboxing of null values gives zero, whereas Java's throw a NPE. // 1. Here we show that we are calling the boxing bridge (the lambda bodies here are compiled into // methods of `(I)Ljava/lang/Object;` / `(I)Ljava/lang/Object;` respectively.) - assertEquals("(Ljava/lang/Object;)Ljava/lang/Object;", implMethodDescriptorFor("(x: Int) => new Object")) - assertEquals("(Ljava/lang/Object;)Ljava/lang/Object;", implMethodDescriptorFor("(x: Object) => 0")) + assertEquals(s"($obj)$obj", implMethodDescriptorFor("(x: Int) => new Object")) + assertEquals(s"($obj)$obj", implMethodDescriptorFor("(x: Object) => 0")) // 2a. We don't need such adaptations for parameters or return values with types that differ // from Object due to other generic substitution, LambdaMetafactory will downcast the arguments. - assertEquals("(Ljava/lang/String;)Ljava/lang/String;", implMethodDescriptorFor("(x: String) => x")) + assertEquals(s"($str)$str", implMethodDescriptorFor("(x: String) => x")) // 2b. Testing 2a. in combination with 1. - assertEquals("(Ljava/lang/Object;)Ljava/lang/String;", implMethodDescriptorFor("(x: Int) => \"\"")) - assertEquals("(Ljava/lang/String;)Ljava/lang/Object;", implMethodDescriptorFor("(x: String) => 0")) + assertEquals(s"($obj)$str", implMethodDescriptorFor("(x: Int) => \"\"")) + assertEquals(s"($str)$obj", implMethodDescriptorFor("(x: String) => 0")) // 3. Specialized functions, don't need any of this as they implement a method like `apply$mcII$sp`, // and the (un)boxing is handled in the base class in code emitted by scalac. assertEquals("(I)I", implMethodDescriptorFor("(x: Int) => x")) + + // non-builtin sams are like specialized functions + compileClasses(compiler)("class VC(private val i: Int) extends AnyVal; trait FunVC { def apply(a: VC): VC }") + assertEquals("(I)I", implMethodDescriptorFor("((x: VC) => x): FunVC")) + + compileClasses(compiler)("trait Fun1[T, U] { def apply(a: T): U }") + assertEquals(s"($obj)$str", implMethodDescriptorFor("(x => x.toString): Fun1[Int, String]")) + assertEquals(s"($obj)$obj", implMethodDescriptorFor("(x => println(x)): Fun1[Int, Unit]")) + assertEquals(s"($obj)$str", implMethodDescriptorFor("((x: VC) => \"\") : Fun1[VC, String]")) + assertEquals(s"($str)$obj", implMethodDescriptorFor("((x: String) => new VC(0)) : Fun1[String, VC]")) + + compileClasses(compiler)("trait Coll[A, Repr] extends Any") + compileClasses(compiler)("final class ofInt(val repr: Array[Int]) extends AnyVal with Coll[Int, Array[Int]]") + + assertEquals(s"([I)$obj", implMethodDescriptorFor("((xs: Array[Int]) => new ofInt(xs)): Array[Int] => Coll[Int, Array[Int]]")) } } |