aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/typer/Applications.scala
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/Applications.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala28
1 files changed, 17 insertions, 11 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 4e43e429b..c4d3e2292 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -20,6 +20,7 @@ import Trees._
import config.Config
import Names._
import StdNames._
+import NameKinds.DefaultGetterName
import ProtoTypes._
import EtaExpansion._
import Inferencing._
@@ -47,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
@@ -68,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
@@ -108,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`.
@@ -345,7 +351,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
}
val getterPrefix =
if ((meth is Synthetic) && meth.name == nme.apply) nme.CONSTRUCTOR else meth.name
- def getterName = getterPrefix.defaultGetterName(n)
+ def getterName = DefaultGetterName(getterPrefix, n)
if (!meth.hasDefaultParams)
EmptyTree
else if (receiver.isEmpty) {
@@ -395,15 +401,14 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
def addTyped(arg: Arg, formal: Type): Type => Type = {
addArg(typedArg(arg, formal), formal)
if (methodType.isParamDependent)
- _.substParam(methodType.newParamRef(n), typeOfArg(arg))
- else
- identity
+ safeSubstParam(_, methodType.paramRefs(n), typeOfArg(arg))
+ else identity
}
def missingArg(n: Int): Unit = {
val pname = methodType.paramNames(n)
fail(
- if (pname contains '$') s"not enough arguments for $methString"
+ if (pname.firstPart contains '$') s"not enough arguments for $methString"
else s"missing argument for parameter $pname of $methString")
}
@@ -719,7 +724,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val lhs1 = typedExpr(lhs)
val liftedDefs = new mutable.ListBuffer[Tree]
val lhs2 = untpd.TypedSplice(liftAssigned(liftedDefs, lhs1))
- val assign = untpd.Assign(lhs2, untpd.Apply(untpd.Select(lhs2, name.init), rhss))
+ val assign = untpd.Assign(lhs2,
+ untpd.Apply(untpd.Select(lhs2, name.asSimpleName.dropRight(1)), rhss))
wrapDefs(liftedDefs, typed(assign))
}