aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala13
-rw-r--r--compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala5
4 files changed, 13 insertions, 18 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index 337f48064..bc55ce638 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -10,6 +10,7 @@ import scala.collection.{ mutable, immutable }
import PartialFunction._
import collection.mutable
import util.common.alwaysZero
+import typer.Applications
object Definitions {
@@ -847,17 +848,9 @@ class Definitions {
}
def isProductSubType(tp: Type)(implicit ctx: Context) =
- (tp derivesFrom ProductType.symbol) && tp.baseClasses.exists(isProductClass)
+ Applications.extractorMemberType(tp, nme._1).exists
- def productArity(tp: Type)(implicit ctx: Context) =
- if (tp derivesFrom ProductType.symbol)
- tp.baseClasses.find(isProductClass) match {
- case Some(prod) => prod.typeParams.length
- case None => -1
- }
- else -1
-
- /** Is `tp` (an alias) of either a scala.FunctionN or a scala.ImplicitFunctionN ? */
+ /** Is `tp` (an alias) of either a scala.FunctionN or a scala.ImplicitFunctionN? */
def isFunctionType(tp: Type)(implicit ctx: Context) = {
val arity = functionArity(tp)
val sym = tp.dealias.typeSymbol
diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
index dbc7666f7..519767389 100644
--- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
@@ -233,7 +233,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
// next: MatchMonad[U]
// returns MatchMonad[U]
def flatMap(prev: Tree, b: Symbol, next: Tree): Tree = {
- val resultArity = defn.productArity(b.info)
+ val resultArity = productArity(b.info)
if (isProductMatch(prev.tpe, resultArity)) {
val nullCheck: Tree = prev.select(defn.Object_ne).appliedTo(Literal(Constant(null)))
ifThenElseZero(
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
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 2760ceba9..c86b15871 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -761,10 +761,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) {
+ defn.isProductSubType(formal) &&
+ Applications.productSelectorTypes(formal).corresponds(params) {
(argType, param) =>
param.tpt.isEmpty || argType <:< typedAheadType(param.tpt).tpe
}