From 5e6364459b697bdde7104bfd87a5f2f56f129722 Mon Sep 17 00:00:00 2001 From: EnzeXing Date: Fri, 29 Aug 2025 23:56:04 -0400 Subject: [PATCH 1/2] Fix unexpected by-name --- .../dotty/tools/dotc/transform/init/Objects.scala | 6 +++--- tests/init-global/pos/multiple-by-name.scala | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 tests/init-global/pos/multiple-by-name.scala diff --git a/compiler/src/dotty/tools/dotc/transform/init/Objects.scala b/compiler/src/dotty/tools/dotc/transform/init/Objects.scala index 92262d528487..61d69621b0ce 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Objects.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Objects.scala @@ -1364,9 +1364,9 @@ class Objects(using Context @constructorOnly): case UnknownValue => reportWarningForUnknownValue("Calling on unknown value. " + Trace.show, Trace.position) case Bottom => Bottom - case ValueSet(values) if values.size == 1 => - evalByNameParam(values.head) - case _: ValueSet | _: Ref | _: ArrayRef | _: Package | SafeValue(_) => + case ValueSet(values) => + values.map(evalByNameParam(_)).join + case _: Ref | _: ArrayRef | _: Package | SafeValue(_) => report.warning("[Internal error] Unexpected by-name value " + value.show + ". " + Trace.show, Trace.position) Bottom end evalByNameParam diff --git a/tests/init-global/pos/multiple-by-name.scala b/tests/init-global/pos/multiple-by-name.scala new file mode 100644 index 000000000000..16a6055089df --- /dev/null +++ b/tests/init-global/pos/multiple-by-name.scala @@ -0,0 +1,15 @@ +class X { + def bar(): Int = 5 +} +class Y extends X { + override def bar(): Int = 6 +} + +object O { + def foo(p: => X) = { + p.bar() + } + + val a = foo(new X) + val b = foo(new Y) +} \ No newline at end of file From de2801b6a110d2fb9ba496dd10bedda33a15b6d5 Mon Sep 17 00:00:00 2001 From: EnzeXing Date: Mon, 1 Sep 2025 20:10:50 -0400 Subject: [PATCH 2/2] Cache result during thunk evaluation --- compiler/src/dotty/tools/dotc/transform/init/Objects.scala | 2 +- tests/init-global/{warn => pos}/i18628_2.scala | 2 +- tests/init-global/{warn => pos}/i18628_3.scala | 2 +- tests/init-global/{warn/i18628.scala => pos/i18628_4.scala} | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename tests/init-global/{warn => pos}/i18628_2.scala (73%) rename tests/init-global/{warn => pos}/i18628_3.scala (72%) rename tests/init-global/{warn/i18628.scala => pos/i18628_4.scala} (70%) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Objects.scala b/compiler/src/dotty/tools/dotc/transform/init/Objects.scala index 61d69621b0ce..c22fd8683949 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Objects.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Objects.scala @@ -1360,7 +1360,7 @@ class Objects(using Context @constructorOnly): case env: Env.EnvRef => Env.ofByName(sym, thisV, Env.EnvSet(Set(env))) } given Scope = byNameEnv - eval(code, thisV, klass) + eval(code, thisV, klass, cacheResult = true) case UnknownValue => reportWarningForUnknownValue("Calling on unknown value. " + Trace.show, Trace.position) case Bottom => Bottom diff --git a/tests/init-global/warn/i18628_2.scala b/tests/init-global/pos/i18628_2.scala similarity index 73% rename from tests/init-global/warn/i18628_2.scala rename to tests/init-global/pos/i18628_2.scala index 7f90f51ccc1a..272207fc1fd1 100644 --- a/tests/init-global/warn/i18628_2.scala +++ b/tests/init-global/pos/i18628_2.scala @@ -2,6 +2,6 @@ object Test: class Box(val x: Int) def recur(a: => Box, b: Box): Int = - a.x + recur(a, b) + b.x // warn + a.x + recur(a, b) + b.x recur(Box(1), Box(2)) diff --git a/tests/init-global/warn/i18628_3.scala b/tests/init-global/pos/i18628_3.scala similarity index 72% rename from tests/init-global/warn/i18628_3.scala rename to tests/init-global/pos/i18628_3.scala index 84ab1d9f6ef3..52826317cb1c 100644 --- a/tests/init-global/warn/i18628_3.scala +++ b/tests/init-global/pos/i18628_3.scala @@ -6,6 +6,6 @@ object Test: class Box(val x: Int) def recur(a: => Box, b: => Box): Int = - a.x + recur(a: @widen(5), b: @widen(5)) + b.x // warn // warn + a.x + recur(a: @widen(5), b: @widen(5)) + b.x recur(Box(1), Box(2)) \ No newline at end of file diff --git a/tests/init-global/warn/i18628.scala b/tests/init-global/pos/i18628_4.scala similarity index 70% rename from tests/init-global/warn/i18628.scala rename to tests/init-global/pos/i18628_4.scala index afd5c14d0b7d..8ea91a381276 100644 --- a/tests/init-global/warn/i18628.scala +++ b/tests/init-global/pos/i18628_4.scala @@ -2,6 +2,6 @@ object Test: class Box(val x: Int) def recur(a: => Box, b: => Box): Int = - a.x + recur(a, b) + b.x // warn // warn + a.x + recur(a, b) + b.x recur(Box(1), Box(2)) \ No newline at end of file