scala/scala — pull request #1643 by retronym (2012-11-18 11:48:54+00:00)
Title: 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. applying an empty argument list 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 expressions, e.g. `qual.foo` is
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.

Review by @odersky