scala/scala — pull request #3522 by adriaanm (2014-02-13 03:26:07+00:00)
Title: SI-6493 more robust symbol handling in existentialTransform

To illustrate the problem, let's compute the result type for

```
def foo = { class Foo { class Bar { val b = 2 }}; val f = new Foo; new f.Bar }
```

Note the inconsistent symbol ids in:

rawSyms = List(value f#49740, class Foo#49739, class Bar#49742)
quantifiers + their infos =
type f.type#49774 <: AnyRef{type Bar#49762 <: AnyRef{val b#49764: Int}} with Singleton,
type Foo#49775 <: AnyRef{type Bar#49770 <: AnyRef{val b#49772: Int}},
type Bar#49773 <: AnyRef{val b#49758: Int}

It makes sense to subst the symbols in tp, but the modifyInfo will have
little effect on quantifiers. Luckily, coevolveSym will fix up some of
the inconsistencies, so that we get `f.type#49774.Bar#49762`, which is
extrapolated to `AnyRef{type Bar#49868 <: AnyRef{val b: Int}}#Bar#49868`.

The intermediate type `f.type#49774.Bar#49762` motivates the need for
the `.substSym` above, as `.subst` does not touch the `Bar#49742` in
the `f#49740.Bar#49742` that we start out with.

The remaining problem is that ExistentialExtrapolation will not consider
type Bar#49868 as existentially bound. Instead, it's looking for the
stale version in quantifiers, Bar#49773. If it was looking for Bar#49868,
the result type would simply be `AnyRef{val b: Int}`

TODO: figure out how to compute the full set of quantifiers for extrapolation
the `doSubst(tp)` will clone more symbols, so we'll probably need to
traverse its result and somehow correlate the contained symbols to
those in `quantifiers`...