blob: aa49e1411339e5f6f05b61fb889001a1022c859b (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
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 }
class C
trait A extends C
trait B extends A
trait TClassParent extends B { 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)
val fClassParent: TClassParent = x => "a"
notLMF(fClassParent)
assert(fClassParent(1) == "a")
}
|