aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/typer/Applications.scala
diff options
context:
space:
mode:
authorOlivier Blanvillain <olivier.blanvillain@gmail.com>2017-04-06 18:35:20 +0200
committerOlivier Blanvillain <olivier.blanvillain@gmail.com>2017-04-06 18:53:30 +0200
commit944e677f437c39d85280c388cab000b5490e4386 (patch)
treee83b50e31f8b3661624fc4ec9fb8c09bdbd0a450 /compiler/src/dotty/tools/dotc/typer/Applications.scala
parentc0ff8adcb4f44a0b01077495a7626d201f8100d5 (diff)
downloaddotty-944e677f437c39d85280c388cab000b5490e4386.tar.gz
dotty-944e677f437c39d85280c388cab000b5490e4386.tar.bz2
dotty-944e677f437c39d85280c388cab000b5490e4386.zip
Decouple Product and pattern-matching
Product pattern use to: - have a `<: Product` requirement - compute the arity of a pattern by looking at `N` in a `ProductN` superclass. This commit changes `<: Product`, instead we look for a `_1` member. The arity is determined by inspecting `_1` to `_N` members instead. --- Here another attempt to formalize Dotty's pattern-matching (base on #1805). This covers the *Extractor Patterns* [section of the spec](https://www.scala-lang.org/files/archive/spec/2.12/08-pattern-matching.html#extractor-patterns). Dotty support 4 different extractor patterns: Boolean Pattern, Product Pattern, Seq Pattern and Name Based Pattern. Boolean Pattern - Extractor defines `def unapply(x: T): Boolean` - Pattern-matching on exactly `0` patterns Product Pattern - Extractor defines `def unapply(x: T): U` - `N > 0` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1` ... `_N: PN` members in `U` - Pattern-matching on exactly `N` patterns with types `P1, P2, ..., PN` Seq Pattern - Extractor defines `def unapplySeq(x: T): U` - `U` has (parameterless `def` or `val`) members `isEmpty: Boolean` and `get: S` - `S <: Seq[V]` - Pattern-matching on any number of pattern with types `V, V, ..., V` Name Based Pattern - Extractor defines `def unapply(x: T): U` - `U` has (parameterless `def` or `val`) members `isEmpty: Boolean` and `get: S` - If there is exactly `1` pattern, pattern-matching on `1` pattern with type `S` - Otherwise fallback to Product Pattern on type `U` In case of ambiguities, *Product Pattern* is preferred over *Name Based Pattern*.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/Applications.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala11
1 files changed, 7 insertions, 4 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 4e43e429b..24d43858d 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -48,12 +48,12 @@ object Applications {
}
/** Does `tp` fit the "product match" conditions as an unapply result type
- * for a pattern with `numArgs` subpatterns>
- * This is the case of `tp` is a subtype of the Product<numArgs> class.
+ * for a pattern with `numArgs` subpatterns?
+ * This is the case of `tp` has members `_1` to `_N` where `N == numArgs`.
*/
def isProductMatch(tp: Type, numArgs: Int)(implicit ctx: Context) =
- 0 <= numArgs && numArgs <= Definitions.MaxTupleArity &&
- tp.derivesFrom(defn.ProductNType(numArgs).typeSymbol)
+ numArgs > 0 && defn.isProductSubType(tp) &&
+ productSelectorTypes(tp).size == numArgs
/** Does `tp` fit the "get match" conditions as an unapply result type?
* This is the case of `tp` has a `get` member as well as a
@@ -68,6 +68,9 @@ object Applications {
sels.takeWhile(_.exists).toList
}
+ def productArity(tp: Type)(implicit ctx: Context) =
+ if (defn.isProductSubType(tp)) productSelectorTypes(tp).size else -1
+
def productSelectors(tp: Type)(implicit ctx: Context): List[Symbol] = {
val sels = for (n <- Iterator.from(0)) yield tp.member(nme.selectorName(n)).symbol
sels.takeWhile(_.exists).toList