scala/scala — pull request #2915 by retronym (2013-09-06 14:51:05+00:00)
Title: SI-7817 Fix regression in structural types 

Calls to structural types are converted to reflective calls
in the `cleanup` phase, which, along with `mixin`, does its work
after `flatten`.

`Symbol#owner` behaves in a phase dependent manner; after flatten
the owner of lifted class is given as the enclosing package.

Except when they're not.

`ModuleSymbol`s representing an object nested inside a class
are viewed dually as modules *and* methods (see the comments on
`isModuleNotMethod` for some background). When it comes time to
flatten, we're presented with a quandary: the method must clearly
stay owned by the enclosing class, but surely the lifted module
should be owned by the enclosing package, to have the same owner
as its associated module class.

The `method` nature of this symbol seems to win:

override def owner = {
if (Statistics.hotEnabled) Statistics.incCounter(ownerCount)
if (!isMethod && needsFlatClasses) rawowner.owner
else rawowner

This wrinkle leads to a wrong turn in `TreeGen#mkAttributedRef`,
which incorrectly rewrites `REF(O)` to `p1.`package`.O`. It seems
this problem has gone unnoticed because the tree emitted referred
to a static symbol (the reflection cache for structural types),
and the backend simply elided the qualifier `p1.package`.

A recent change to the backend makes it more conservative about
dropping qualifiers on the floor, and it started emitting a reference
to a package object that doesn't exist.

This commit despairingly checks `isDefinedInPackage` of both the
module *and* the module class. The test cases from the previous
commit illustrated the status quo, and this commit updates the
joint compilation test with the bug fix. A new test is to show that
the symptom (structural type crash) is now fixed.

Review by @paulp. I'd like to iterate to a better spot for the solution, but I feel we're a bit constrained by the schizophrenic symbol representation.

/cc @gkossakowski we probably should get this into M5, I'm sure ScalaTest won't be the only codebase that feels it.