blob: fa0443f66948734474e67a1b84a990e6c37f31c9 (
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
|
// A test for the case where the outer field of class B#J should be eliminated.
import reflect.ClassTag
abstract class A {
abstract class I
val foo = this
}
class B extends A {
class J extends I {
val bar = foo
}
type II = I
class K extends II {
val bar = foo
}
class L extends (I @annotation.tailrec) {
val bar = foo
}
}
class C extends A {
val c: C = this
class M extends c.I {
val bar = foo
}
}
object Test extends App {
val b = new B
val c0 = new C
val c = new { override val c = c0 } with C
assert((new b.J).bar eq b)
assert((new b.K).bar eq b)
assert((new b.L).bar eq b)
assert((new c.M).bar eq c)
def checkOuterFields[C: ClassTag](expected: Int) {
val cls = implicitly[ClassTag[C]].runtimeClass
val outerFields = cls.getDeclaredFields().filter(_.getName.contains("$outer"))
assert(outerFields.size == expected, outerFields.map(_.getName))
}
checkOuterFields[A#I](1) // the base class must have the $outer pointer
checkOuterFields[B#J](0) // reuse parent class' $outer pointer
checkOuterFields[B#K](0) // ... through an alias
checkOuterFields[B#L](0) // ... through the annotated type
checkOuterFields[C#M](1) // different prefix, can't share.
}
|