summaryrefslogtreecommitdiff
path: root/test/files/run/t6677b.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2012-11-17 22:04:19 +0100
committerJason Zaugg <jzaugg@gmail.com>2012-11-18 14:31:14 +0100
commit2aa68419c09ba16e4e7fdc71e4a3ad9e8b261e87 (patch)
tree7a23a472768adad7bd060ed1cb5119a004414297 /test/files/run/t6677b.scala
parent2d62ab248d07f10fd89a68b12565259ca861e1e9 (diff)
downloadscala-2aa68419c09ba16e4e7fdc71e4a3ad9e8b261e87.tar.gz
scala-2aa68419c09ba16e4e7fdc71e4a3ad9e8b261e87.tar.bz2
scala-2aa68419c09ba16e4e7fdc71e4a3ad9e8b261e87.zip
SI-6677 Insert required cast in `new qual.foo.T`
Short version: we sometimes need to rewrite this as new T(qual.asInstanceOf[OwnerOfFoo].foo) Long version: `adaptMember` in Erasure performs a few tasks, among them: 1. adding an empty argument list to qualifiers in `new qual.T` for which `qual` is a val template member that has (post uncurry) a MethodType with an empty parameter list. The same rewriting was already applied in uncurry for such qualifiers appearing in other contexts, e.g. `qual.foo` was already rewritten to `qual().foo`. 2. casting, if necessary, the qualifier in `Select(qual, name)` to the type of owner of the symbol that this selection references. This can be neccesary with compound types: - some val class member has type `A with B`; - we instantiate `new ab.valMemberOfB.T` - we must pass `ab.valMemberOfB` to the constructor of `T` as the `$outer` pointer - we must cast `ab` to `B` before calling `valMemberOfB`. Failure to insert this cast can lead to a LinkageError or a VerifyError. However, if 1) was performed, 2) was not. The error is pretty easy to trigger with the new reflection API: class Test { val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror def error { new cm.universe.Traverser // java.lang.VerifyError } def okay1 { val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror new cm.universe.Traverser } } The fix applied here to `adaptMember` mirrors the existing implementation of `adaptType`.
Diffstat (limited to 'test/files/run/t6677b.scala')
-rw-r--r--test/files/run/t6677b.scala33
1 files changed, 33 insertions, 0 deletions
diff --git a/test/files/run/t6677b.scala b/test/files/run/t6677b.scala
new file mode 100644
index 0000000000..e4fe5e3722
--- /dev/null
+++ b/test/files/run/t6677b.scala
@@ -0,0 +1,33 @@
+trait U {
+ trait U1 {
+ class X
+ }
+ type U11 <: U1
+ val u : U11 = null.asInstanceOf[U11]
+}
+trait A extends U
+
+trait B extends U {
+ def foo = ""
+ class U11 extends U1 { class X extends super.X { foo } } // refer to foo to add $outer pointer
+ override val u = new U11
+}
+class C {
+ val ab: A with B = new A with B // `B with A` works.
+
+ def foo {
+ // fails
+ new ab.u.X
+
+ // works:
+ val u = ab.u
+ new u.X
+ }
+}
+object Test {
+ def main(args: Array[String]) {
+ // java.lang.NoSuchMethodError: A.u()LB$U11;
+ // at C.foo(t6677b.scala:23)
+ new C().foo
+ }
+}