diff options
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/Applications.scala')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Applications.scala | 28 |
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)) } |