Skip to content

Commit 76aed5e

Browse files
committed
Add explanation
1 parent bdbbc51 commit 76aed5e

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,28 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
258258
// method could be constructed as the definition site of the type variable for
259259
// that default constructor. This would interpolate type variables too early,
260260
// causing lots of tests (among them tasty_unpickleScala2) to fail.
261+
//
262+
// The test case is in i1757.scala. Here we have a variable `s` and a method `cpy`
263+
// defined like this:
264+
//
265+
// var s
266+
// def cpy[X](b: List[Int] = b): B[X] = new B[X](b)
267+
//
268+
// The call `s.cpy()` then gets expanded to
269+
//
270+
// { val $1$: B[Int] = this.s
271+
// $1$.cpy[X']($1$.cpy$default$1[X']
272+
// }
273+
//
274+
// A type variable gets interpolated if it does not appear in the type
275+
// of the current tree and the current tree contains the variable's "definition".
276+
// Previously, the polymorphic function tree to which the variable was first added
277+
// was taken as the variable's definition. But that fails here because that
278+
// tree was `s.cpy` but got transformed into `$1$.cpy`. We now take the type argument
279+
// [X'] of the variable as its definition tree, which is more robust. But then
280+
// it's crucial that the type tree is not copied directly as argument to
281+
// `cpy$default$1`. If it was, the variable `X'` would already be interpolated
282+
// when typing the default argument, which is too early.
261283
spliceMeth(meth, fn).appliedToTypes(targs.tpes)
262284
case _ => meth
263285
}

0 commit comments

Comments
 (0)