summaryrefslogtreecommitdiff
path: root/test/files/pos/t8267.scala
Commit message (Collapse)AuthorAgeFilesLines
* SI-8267 Avoid existentials after polymorphic overload resolutionJason Zaugg2014-10-021-0/+33
... 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.