From 4700e3f3bac054f119c8af489d1b2dd6848c8798 Mon Sep 17 00:00:00 2001 From: odersky Date: Fri, 9 Feb 2024 15:50:03 +0100 Subject: [PATCH] More careful type variable instance improvements The previous code tried to recursively apply the current instance of FullyDefinedAccumulator to the prospective instance type. This can have unforeseen side-effects, as i19637 shows. We now are more conservative: We check that the prospective instance type is already fully defined without the possibility to instantiate more type variables. This still passes the test cases that type variable improvement solves and avoids the problem with #19637. Fixes #19637 --- compiler/src/dotty/tools/dotc/typer/Inferencing.scala | 2 +- tests/pos/i19637.scala | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i19637.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index fd8507a7d961..ed37a869d612 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -205,7 +205,7 @@ object Inferencing { private def instantiate(tvar: TypeVar, fromBelow: Boolean): Boolean = if fromBelow && force.canImprove(tvar) then val inst = tvar.typeToInstantiateWith(fromBelow = true) - if apply(true, inst) then + if isFullyDefined(inst, ForceDegree.none) then // need to recursively check before improving, since improving adds type vars // which should not be instantiated at this point val better = improve(tvar)(inst) diff --git a/tests/pos/i19637.scala b/tests/pos/i19637.scala new file mode 100644 index 000000000000..53e609407bd0 --- /dev/null +++ b/tests/pos/i19637.scala @@ -0,0 +1,11 @@ +import java.util.stream.* +import java.util.function.* + +val map: java.util.Map[String, String] = Stream.of("1", "2", "3").collect(Collectors.toMap( + (s: String) => s, + Function.identity(), + { + case ("1", "1") => "1" + case (_, l) => l + } +))