diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2017-04-11 12:01:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-11 12:01:17 +0200 |
commit | 4868fb29580a67c7a1560d5c1c7cc658e2634359 (patch) | |
tree | 1deed7fb92912f09b810e905e351fe4cd796cc6b /compiler/src/dotty/tools/dotc/typer | |
parent | 579571e05a08120133173933e7eaf2555846d1d7 (diff) | |
parent | 198b5cec531a8e0d6c121cc425e19a54b7818868 (diff) | |
download | dotty-4868fb29580a67c7a1560d5c1c7cc658e2634359.tar.gz dotty-4868fb29580a67c7a1560d5c1c7cc658e2634359.tar.bz2 dotty-4868fb29580a67c7a1560d5c1c7cc658e2634359.zip |
Merge pull request #1938 from dotty-staging/named-based-patmat
Change case class desugaring and decouple Products and name-based-pattern-matching
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Applications.scala | 15 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Typer.scala | 5 |
2 files changed, 12 insertions, 8 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 2f2af9868..c4d3e2292 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -48,13 +48,15 @@ object Applications { ref.info.widenExpr.dealias } + def canProductMatch(tp: Type)(implicit ctx: Context) = + extractorMemberType(tp, nme._1).exists + /** 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 && productArity(tp) == 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 @@ -69,6 +71,9 @@ object Applications { sels.takeWhile(_.exists).toList } + def productArity(tp: Type)(implicit ctx: Context) = + if (canProductMatch(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 @@ -109,7 +114,7 @@ object Applications { getUnapplySelectors(getTp, args, pos) else if (unapplyResult isRef defn.BooleanClass) Nil - else if (defn.isProductSubType(unapplyResult)) + else if (canProductMatch(unapplyResult)) productSelectorTypes(unapplyResult) // this will cause a "wrong number of arguments in pattern" error later on, // which is better than the message in `fail`. diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index e6236d122..ba55dfe30 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -762,10 +762,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit /** Is `formal` a product type which is elementwise compatible with `params`? */ def ptIsCorrectProduct(formal: Type) = { - val pclass = defn.ProductNType(params.length).symbol isFullyDefined(formal, ForceDegree.noBottom) && - formal.derivesFrom(pclass) && - formal.baseArgTypes(pclass).corresponds(params) { + Applications.canProductMatch(formal) && + Applications.productSelectorTypes(formal).corresponds(params) { (argType, param) => param.tpt.isEmpty || argType <:< typedAheadType(param.tpt).tpe } |