aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/typer/Applications.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-11 20:52:03 +0100
committerMartin Odersky <odersky@gmail.com>2017-03-14 12:05:29 +0100
commit86bf552cd421288b00525eb1a264652ee32d742d (patch)
tree139b0602a72c2e4fdec8f39fdfe596666846b6a1 /compiler/src/dotty/tools/dotc/typer/Applications.scala
parent3257dcc590e42b223696b6b8e389e0a3613db93f (diff)
downloaddotty-86bf552cd421288b00525eb1a264652ee32d742d.tar.gz
dotty-86bf552cd421288b00525eb1a264652ee32d742d.tar.bz2
dotty-86bf552cd421288b00525eb1a264652ee32d742d.zip
Take parameter dependencies into account
Take parameter dependencies into account when typechecking arguments.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/Applications.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala26
1 files changed, 21 insertions, 5 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index b459e2745..5dcf16b62 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -178,6 +178,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
*/
protected def normalizedFun: Tree
+ protected def typeOfArg(arg: Arg): Type
+
/** If constructing trees, pull out all parts of the function
* which are not idempotent into separate prefix definitions
*/
@@ -380,8 +382,16 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
if (success) formals match {
case formal :: formals1 =>
- def addTyped(arg: Arg, formal: Type) =
+ /** Add result of typing argument `arg` against parameter type `formal`.
+ * @return A type transformation to apply to all arguments following this one.
+ */
+ def addTyped(arg: Arg, formal: Type): Type => Type = {
addArg(typedArg(arg, formal), formal)
+ if (methodType.isParamDependent)
+ _.substParam(MethodParam(methodType, n), typeOfArg(arg))
+ else
+ identity
+ }
def missingArg(n: Int): Unit = {
val pname = methodType.paramNames(n)
@@ -395,8 +405,10 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val getter = findDefaultGetter(n + numArgs(normalizedFun))
if (getter.isEmpty) missingArg(n)
else {
- addTyped(treeToArg(spliceMeth(getter withPos normalizedFun.pos, normalizedFun)), formal)
- matchArgs(args1, formals1, n + 1)
+ val substParam = addTyped(
+ treeToArg(spliceMeth(getter withPos normalizedFun.pos, normalizedFun)),
+ formal)
+ matchArgs(args1, formals1.mapconserve(substParam), n + 1)
}
}
@@ -420,8 +432,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
case EmptyTree :: args1 =>
tryDefault(n, args1)
case arg :: args1 =>
- addTyped(arg, formal)
- matchArgs(args1, formals1, n + 1)
+ val substParam = addTyped(arg, formal)
+ matchArgs(args1, formals1.mapconserve(substParam), n + 1)
case nil =>
tryDefault(n, args)
}
@@ -477,6 +489,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
def argType(arg: Tree, formal: Type): Type = normalize(arg.tpe, formal)
def treeToArg(arg: Tree): Tree = arg
def isVarArg(arg: Tree): Boolean = tpd.isWildcardStarArg(arg)
+ def typeOfArg(arg: Tree): Type = arg.tpe
def harmonizeArgs(args: List[Tree]) = harmonize(args)
}
@@ -494,6 +507,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
def argType(arg: Type, formal: Type): Type = arg
def treeToArg(arg: Tree): Type = arg.tpe
def isVarArg(arg: Type): Boolean = arg.isRepeatedParam
+ def typeOfArg(arg: Type): Type = arg
def harmonizeArgs(args: List[Type]) = harmonizeTypes(args)
}
@@ -592,6 +606,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
extends TypedApply(app, fun, methRef, proto.args, resultType) {
def typedArg(arg: untpd.Tree, formal: Type): TypedArg = proto.typedArg(arg, formal.widenExpr)
def treeToArg(arg: Tree): untpd.Tree = untpd.TypedSplice(arg)
+ def typeOfArg(arg: untpd.Tree) = proto.typeOfArg(arg)
}
/** Subclass of Application for type checking an Apply node with typed arguments. */
@@ -603,6 +618,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
// not match the abstract method in Application and an abstract class error results.
def typedArg(arg: tpd.Tree, formal: Type): TypedArg = arg
def treeToArg(arg: Tree): Tree = arg
+ def typeOfArg(arg: Tree) = arg.tpe
}
/** If `app` is a `this(...)` constructor call, the this-call argument context,