From 2aa68419c09ba16e4e7fdc71e4a3ad9e8b261e87 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 17 Nov 2012 22:04:19 +0100 Subject: 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`. --- test/files/run/t6677.scala | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 test/files/run/t6677.scala (limited to 'test/files/run/t6677.scala') diff --git a/test/files/run/t6677.scala b/test/files/run/t6677.scala new file mode 100644 index 0000000000..e6eaf6a498 --- /dev/null +++ b/test/files/run/t6677.scala @@ -0,0 +1,28 @@ + +class Test { + val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror + def error { + new cm.universe.Traverser // java.lang.VerifyError: (class: Test, method: error signature: ()V) Incompatible object argument for function call + + } + + def okay1 { + val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror + + new cm.universe.Traverser + } + + def okay2 { + val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror + val u: reflect.runtime.universe.type = cm.universe + new u.Traverser + } +} + +object Test { + def main(args: Array[String]) { + new Test().error + new Test().okay1 + new Test().okay2 + } +} -- cgit v1.2.3