From 76aed5e468d6e9fa2279241fe8bd7f06b2c3f4e0 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 2 Dec 2016 09:05:23 +0100 Subject: Add explanation --- .../src/dotty/tools/dotc/typer/Applications.scala | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'compiler/src/dotty') diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index b10f64adb..11121e1f3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -258,6 +258,28 @@ trait Applications extends Compatibility { self: Typer with Dynamic => // 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. + // + // The test case is in i1757.scala. Here we have a variable `s` and a method `cpy` + // defined like this: + // + // var s + // def cpy[X](b: List[Int] = b): B[X] = new B[X](b) + // + // The call `s.cpy()` then gets expanded to + // + // { val $1$: B[Int] = this.s + // $1$.cpy[X']($1$.cpy$default$1[X'] + // } + // + // A type variable gets interpolated if it does not appear in the type + // of the current tree and the current tree contains the variable's "definition". + // Previously, the polymorphic function tree to which the variable was first added + // was taken as the variable's definition. But that fails here because that + // tree was `s.cpy` but got transformed into `$1$.cpy`. We now take the type argument + // [X'] of the variable as its definition tree, which is more robust. But then + // it's crucial that the type tree is not copied directly as argument to + // `cpy$default$1`. If it was, the variable `X'` would already be interpolated + // when typing the default argument, which is too early. spliceMeth(meth, fn).appliedToTypes(targs.tpes) case _ => meth } -- cgit v1.2.3