|
... which can be introduced by `memberType` for methods
with parameter types dependent on class type parameters.
Here's an example of such a type:
```
scala> class Bippy { trait Foo[A] }
defined class Bippy
scala> final class RichBippy[C <: Bippy with Singleton](val c1: C) {
| def g[A](x: A)(ev: c1.Foo[A]): Int = 2
| }
defined class RichBippy
scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'. **
** scala.tools.nsc._ has been imported **
** global._, definitions._ also imported **
** Try :help, :vals, power.<tab> **
scala> val g = typeOf[RichBippy[_]].member(TermName("g"))
g: $r.intp.global.Symbol = method g
scala> val c = new Bippy
c: Bippy = Bippy@92e2c93
scala> val memberType = typeOf[RichBippy[c.type]].memberType(g)
memberType: $r.intp.global.Type = ([A](x: A)(ev: _7.c1.Foo[A])Int) forSome { val _7: RichBippy[c.type] }
```
In this example, if we were to typecheck the selection
`new RichBippy[c.type].g` that existential type would be short lived.
Consider this approximation of `Typer#typedInternal`:
```scala
val tree1: Tree = typed1(tree, mode, ptWild)
val result = adapt(tree1, mode, ptPlugins, tree)
```
Given that `tree1.tpe` is not an overloaded, adapt will find its
way to:
```
case tp if mode.typingExprNotLhs && isExistentialType(tp) =>
adapt(tree setType tp.dealias.skolemizeExistential(context.owner, tree), mode, pt, original)
```
Which would open the existential as per:
```
scala> memberType.skolemizeExistential
res2: $r.intp.global.Type = [A](x: A)(ev: _7.c1.Foo[A])Int
```
However, if do have overloaded alternatives, as in the test case,
we have to remember to call `adapt` again *after* we have picked
the winning alternative.
We actually don't have a centralised place where overload resolution
occurs, as the process differs depending on the context of the
selection. (Are there explicit type arguments? Inferred type
arguments? Do we need to use the expected type to pick a winner?)
This commit finds the existing places that call adapt after
overloade resolution and routes those calls through a marker
method. It then adds one more call to this in `inferPolyAlternatives`,
which fixes the bug.
|