From 5491e59569b85949ffb9d6e825c9e337adccdf2d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 1 Dec 2016 18:46:36 +0100 Subject: Fix #1757: Be more careful about positions of type variable binders We interpolate a type variable if the current tree contains the type variables binding tree. Previously, this was the application owning the variable. However, sometimes this tree is transformed so that the containment test fails, and type variables are instantiated too late (in the case of #1757 this was never). We fix this by - setting the binding tree to the type tree that first contains the type variable - making sure that tree is never copied literally anywhere else. It's a tricky dance, but I believe we got it right now. --- compiler/src/dotty/tools/dotc/typer/Applications.scala | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'compiler/src/dotty/tools/dotc/typer/Applications.scala') diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 6c398cd72..b10f64adb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -250,8 +250,15 @@ trait Applications extends Compatibility { self: Typer with Dynamic => /** Splice new method reference into existing application */ def spliceMeth(meth: Tree, app: Tree): Tree = app match { - case Apply(fn, args) => Apply(spliceMeth(meth, fn), args) - case TypeApply(fn, targs) => TypeApply(spliceMeth(meth, fn), targs) + case Apply(fn, args) => + spliceMeth(meth, fn).appliedToArgs(args) + case TypeApply(fn, targs) => + // Note: It is important that the type arguments `targs` are passed in new trees + // instead of being spliced in literally. Otherwise, a type argument to a default + // method could be constructed as the definition site of the type variable for + // that default constructor. This would interpolate type variables too early, + // causing lots of tests (among them tasty_unpickleScala2) to fail. + spliceMeth(meth, fn).appliedToTypes(targs.tpes) case _ => meth } @@ -333,7 +340,7 @@ 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 appPos, normalizedFun)), formal) + addTyped(treeToArg(spliceMeth(getter withPos normalizedFun.pos, normalizedFun)), formal) matchArgs(args1, formals1, n + 1) } } -- cgit v1.2.3