|
The unified treatment of classical and named-based pattern matching
does not correctly handle the generalization of "tuple capture".
By "tuple capture", I mean:
```
scala> object Extractor { def unapply(a: Any): Option[(Int, String)] = Some((1, "2")) }
defined object Extractor
scala> "" match { case Extractor(x: Int, y: String) => }
scala> "" match { case Extractor(xy : (Int, String)) => }
warning: there was one deprecation warning; re-run with -deprecation for details
scala> :warnings
<console>:9: warning: object Extractor expects 2 patterns to hold (Int, String) but crushing into 2-tuple to fit single pattern (SI-6675)
"" match { case Extractor(xy : (Int, String)) => }
^
```
Name based pattern matching, new in Scala 2.11, allows one to
deconstruct the elements that structurally resembles `ProductN`:
```
scala> class P2(val _1: Int, val _2: String)
defined class P2
scala> object Extractor { def unapply(a: Any): Option[P2] = Some(new P2(1, "2")) }
defined object Extractor
scala> "" match { case Extractor(x: Int, y: String) => }
```
However, attempting to extract the `P2` in its entirety leads to
an internal error:
```
scala> "" match { case Extractor(p2: P2) => }
<console>:10: warning: fruitless type test: a value of type (Int, String) cannot also be a P2
"" match { case Extractor(p2: P2) => }
^
<console>:10: error: error during expansion of this match (this is a scalac bug).
The underlying error was: type mismatch;
found : P2
required: (Int, String)
"" match { case Extractor(p2: P2) => }
^
```
Note that this match was legal and warning free in 2.10.
This commit avoids the hard-coded assumption that the "tuple capture"
results in a `TupleN`, and instead keeps track of the product-ish
type from which we extracted the element types. I have also opted not
to limit the deprecation warning to `TupleN` extractors.
|