paulp/scala — pull request #13 by retronym (2014-01-09 09:31:56+00:00)
Title: SI-8128 Fix regression in extractors returning existentials

The advent of the named based pattern matcher brought with it
a change in the way we determine the type of the value in the
"match monad". We used to take the base type to `Option` or `Seq`
(guided by the method name in `unapply` vs `unapplySeq`), and
simply use the type argument.

Name-based patmat, instead, uses the result type of methods in the
type. For example, the element type of an Option-like extractor
result is given by the result type of the no-args `get` method.

This approach, however, swiftly runs aground when navigating the
existential atolls. Here's why:

scala> class F[_]
defined class F

scala> val tp = typeOf[Some[F[X]] forSome { type X }]
warning: there were 1 feature warning(s); re-run with -feature for details
tp: $r.intp.global.Type = scala.this.Some[F[X]] forSome { type X }

scala> tp.baseType(typeOf[Option[_]].typeSymbol).typeArgs.head
res10: $r.intp.global.Type = F[X] forSome { type X }

scala> tp.memberType(tp.member(nme.get)).finalResultType
res11: $r.intp.global.Type = F[X]

`res10` corresponds to 2.10.x approach in `matchMonadResult`.
`res11` corresponds to the new approach in `resultOfMatchingMethod`.

The last result is not wrapped by the existential type. This results
in errors like (shown under -Ydebug to turn un accurate printing of
skolems):

error: error during expansion of this match (this is a scalac bug).
The underlying error was: type mismatch;
found : _$1&0 where type _$1&0
required: _$1
(0: Any) match {
^
one error found

This commit addresses the regression in 2.10.x compatible extractors
by using the 2.10 approach for them.

The residual problem is shown in the enclosed pending test.