From a5091c3b987dc8f9571bb689dacedf823067998d Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Fri, 4 Aug 2023 23:28:17 +0200 Subject: [PATCH] Only lift inner expressions when lifting repeated `Typed` arguments closes lampepfl#18233 --- .../dotty/tools/dotc/typer/EtaExpansion.scala | 3 +- .../{run => coverage/run/i16940}/i16940.scala | 3 - .../run/i16940/i16940.scoverage.check | 343 ++++++++++++++++++ .../coverage/run/i18233-min/i18233-min.scala | 13 + .../run/i18233-min/i18233-min.scoverage.check | 258 +++++++++++++ tests/coverage/run/i18233/i18233.scala | 9 + .../run/i18233/i18233.scoverage.check | 156 ++++++++ 7 files changed, 781 insertions(+), 4 deletions(-) rename tests/{run => coverage/run/i16940}/i16940.scala (91%) create mode 100644 tests/coverage/run/i16940/i16940.scoverage.check create mode 100644 tests/coverage/run/i18233-min/i18233-min.scala create mode 100644 tests/coverage/run/i18233-min/i18233-min.scoverage.check create mode 100644 tests/coverage/run/i18233/i18233.scala create mode 100644 tests/coverage/run/i18233/i18233.scoverage.check diff --git a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala index b1513df777ec..8e5ec7525d48 100644 --- a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala +++ b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala @@ -76,10 +76,11 @@ abstract class Lifter { tree } - /** Lift a function argument, stripping any NamedArg wrapper */ + /** Lift a function argument, stripping any NamedArg wrapper and repeated Typed trees */ private def liftArg(defs: mutable.ListBuffer[Tree], arg: Tree, prefix: TermName = EmptyTermName)(using Context): Tree = arg match { case arg @ NamedArg(name, arg1) => cpy.NamedArg(arg)(name, lift(defs, arg1, prefix)) + case arg @ Typed(arg1, tpt) if tpt.typeOpt.isRepeatedParam => cpy.Typed(arg)(lift(defs, arg1, prefix), tpt) case arg => lift(defs, arg, prefix) } diff --git a/tests/run/i16940.scala b/tests/coverage/run/i16940/i16940.scala similarity index 91% rename from tests/run/i16940.scala rename to tests/coverage/run/i16940/i16940.scala index 5c16b6d3333d..9d1c80b1a5cd 100644 --- a/tests/run/i16940.scala +++ b/tests/coverage/run/i16940/i16940.scala @@ -1,6 +1,3 @@ -// scalac: -coverage-out:coverage -// scalajs: --skip - import concurrent.ExecutionContext.Implicits.global import scala.concurrent.* import scala.concurrent.duration.* diff --git a/tests/coverage/run/i16940/i16940.scoverage.check b/tests/coverage/run/i16940/i16940.scoverage.check new file mode 100644 index 000000000000..8981e91283d5 --- /dev/null +++ b/tests/coverage/run/i16940/i16940.scoverage.check @@ -0,0 +1,343 @@ +# Coverage data, format version: 3.0 +# Statement data: +# - id +# - source path +# - package name +# - class name +# - class type (Class, Object or Trait) +# - full class name +# - method name +# - start offset +# - end offset +# - line number +# - symbol name +# - tree name +# - is branch +# - invocations count +# - is ignored +# - description (can be multi-line) +# ' ' sign +# ------------------------------------------ +0 +i16940/i16940.scala + +Test$ +Object +.Test$ + +353 +552 +18 +result +Apply +false +0 +false +Await.result(\n Future.sequence(Seq(brokenSynchronizedBlock(false), brokenSynchronizedBlock(true)))\n .map { result =>\n println(test)\n assert(test == 2)\n },\n 3.seconds\n ) + +1 +i16940/i16940.scala + +Test$ +Object +.Test$ + +371 +533 +19 +map +Apply +false +0 +false +Future.sequence(Seq(brokenSynchronizedBlock(false), brokenSynchronizedBlock(true)))\n .map { result =>\n println(test)\n assert(test == 2)\n } + +2 +i16940/i16940.scala + +Test$ +Object +.Test$ + +371 +454 +19 +sequence +Apply +false +0 +false +Future.sequence(Seq(brokenSynchronizedBlock(false), brokenSynchronizedBlock(true))) + +3 +i16940/i16940.scala + +Test$ +Object +.Test$ + +387 +453 +19 +apply +Apply +false +0 +false +Seq(brokenSynchronizedBlock(false), brokenSynchronizedBlock(true)) + +4 +i16940/i16940.scala + +Test$ +Object +.Test$ + +387 +390 +19 +Seq +Ident +false +0 +false +Seq + +5 +i16940/i16940.scala + +Test$ +Object +.Test$ + +391 +421 +19 +brokenSynchronizedBlock +Apply +false +0 +false +brokenSynchronizedBlock(false) + +6 +i16940/i16940.scala + +Test$ +Object +.Test$ + +423 +452 +19 +brokenSynchronizedBlock +Apply +false +0 +false +brokenSynchronizedBlock(true) + +7 +i16940/i16940.scala + +Test$ +Object +.Test$ +$anonfun +486 +499 +21 +println +Apply +false +0 +false +println(test) + +8 +i16940/i16940.scala + +Test$ +Object +.Test$ +$anonfun +508 +525 +22 +assertFailed +Apply +false +0 +false +assert(test == 2) + +9 +i16940/i16940.scala + +Test$ +Object +.Test$ +$anonfun +508 +525 +22 +assertFailed +Apply +true +0 +false +assert(test == 2) + +10 +i16940/i16940.scala + +Test$ +Object +.Test$ +$anonfun +508 +525 +22 + +Literal +true +0 +false +assert(test == 2) + +11 +i16940/i16940.scala + +Test$ +Object +.Test$ + +539 +548 +24 +seconds +Select +false +0 +false +3.seconds + +12 +i16940/i16940.scala + +i16940$package$ +Object +.i16940$package$ +brokenSynchronizedBlock +189 +323 +6 +apply +Apply +false +0 +false +Future {\n if (option) {\n Thread.sleep(500)\n }\n synchronized {\n val tmp = test\n Thread.sleep(1000)\n test = tmp + 1\n }\n} + +13 +i16940/i16940.scala + +i16940$package$ +Object +.i16940$package$ +brokenSynchronizedBlock +218 +235 +8 +sleep +Apply +false +0 +false +Thread.sleep(500) + +14 +i16940/i16940.scala + +i16940$package$ +Object +.i16940$package$ +brokenSynchronizedBlock +212 +239 +7 + +Block +true +0 +false +{\n Thread.sleep(500)\n } + +15 +i16940/i16940.scala + +i16940$package$ +Object +.i16940$package$ +brokenSynchronizedBlock +239 +239 +9 + +Literal +true +0 +false + + +16 +i16940/i16940.scala + +i16940$package$ +Object +.i16940$package$ +brokenSynchronizedBlock +242 +321 +10 +synchronized +Apply +false +0 +false +synchronized {\n val tmp = test\n Thread.sleep(1000)\n test = tmp + 1\n } + +17 +i16940/i16940.scala + +i16940$package$ +Object +.i16940$package$ +brokenSynchronizedBlock +280 +298 +12 +sleep +Apply +false +0 +false +Thread.sleep(1000) + +18 +i16940/i16940.scala + +i16940$package$ +Object +.i16940$package$ +brokenSynchronizedBlock +128 +155 +6 +brokenSynchronizedBlock +DefDef +false +0 +false +def brokenSynchronizedBlock + diff --git a/tests/coverage/run/i18233-min/i18233-min.scala b/tests/coverage/run/i18233-min/i18233-min.scala new file mode 100644 index 000000000000..67ec5824f57e --- /dev/null +++ b/tests/coverage/run/i18233-min/i18233-min.scala @@ -0,0 +1,13 @@ +def aList = + List(Array[String]()*) + +def arr = + Array("abc", "def") + +def anotherList = + List(arr*) + +object Test extends App { + println(aList) + println(anotherList) +} diff --git a/tests/coverage/run/i18233-min/i18233-min.scoverage.check b/tests/coverage/run/i18233-min/i18233-min.scoverage.check new file mode 100644 index 000000000000..5699003d5564 --- /dev/null +++ b/tests/coverage/run/i18233-min/i18233-min.scoverage.check @@ -0,0 +1,258 @@ +# Coverage data, format version: 3.0 +# Statement data: +# - id +# - source path +# - package name +# - class name +# - class type (Class, Object or Trait) +# - full class name +# - method name +# - start offset +# - end offset +# - line number +# - symbol name +# - tree name +# - is branch +# - invocations count +# - is ignored +# - description (can be multi-line) +# ' ' sign +# ------------------------------------------ +0 +i18233-min/i18233-min.scala + +Test$ +Object +.Test$ + +131 +145 +10 +println +Apply +false +0 +false +println(aList) + +1 +i18233-min/i18233-min.scala + +Test$ +Object +.Test$ + +139 +144 +10 +aList +Ident +false +0 +false +aList + +2 +i18233-min/i18233-min.scala + +Test$ +Object +.Test$ + +148 +168 +11 +println +Apply +false +0 +false +println(anotherList) + +3 +i18233-min/i18233-min.scala + +Test$ +Object +.Test$ + +156 +167 +11 +anotherList +Ident +false +0 +false +anotherList + +4 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +aList +14 +36 +1 +apply +Apply +false +0 +false +List(Array[String]()*) + +5 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +aList +14 +18 +1 +List +Ident +false +0 +false +List + +6 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +aList +19 +34 +1 +apply +Apply +false +0 +false +Array[String]() + +7 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +aList +0 +9 +0 +aList +DefDef +false +0 +false +def aList + +8 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +arr +50 +69 +4 +apply +Apply +false +0 +false +Array("abc", "def") + +9 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +arr +38 +45 +3 +arr +DefDef +false +0 +false +def arr + +10 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +anotherList +91 +101 +7 +apply +Apply +false +0 +false +List(arr*) + +11 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +anotherList +91 +95 +7 +List +Ident +false +0 +false +List + +12 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +anotherList +96 +99 +7 +arr +Ident +false +0 +false +arr + +13 +i18233-min/i18233-min.scala + +i18233-min$package$ +Object +.i18233-min$package$ +anotherList +71 +86 +6 +anotherList +DefDef +false +0 +false +def anotherList + diff --git a/tests/coverage/run/i18233/i18233.scala b/tests/coverage/run/i18233/i18233.scala new file mode 100644 index 000000000000..e3978d90ca38 --- /dev/null +++ b/tests/coverage/run/i18233/i18233.scala @@ -0,0 +1,9 @@ +enum Foo: + case Bar, Baz + +object Foo: + def render = List(values.tail*).mkString + +object Test extends App { + println(Foo.render) +} diff --git a/tests/coverage/run/i18233/i18233.scoverage.check b/tests/coverage/run/i18233/i18233.scoverage.check new file mode 100644 index 000000000000..6c8ce6bf38ba --- /dev/null +++ b/tests/coverage/run/i18233/i18233.scoverage.check @@ -0,0 +1,156 @@ +# Coverage data, format version: 3.0 +# Statement data: +# - id +# - source path +# - package name +# - class name +# - class type (Class, Object or Trait) +# - full class name +# - method name +# - start offset +# - end offset +# - line number +# - symbol name +# - tree name +# - is branch +# - invocations count +# - is ignored +# - description (can be multi-line) +# ' ' sign +# ------------------------------------------ +0 +i18233/i18233.scala + +Foo$ +Object +.Foo$ +render +54 +72 +4 +apply +Apply +false +0 +false +List(values.tail*) + +1 +i18233/i18233.scala + +Foo$ +Object +.Foo$ +render +54 +58 +4 +List +Ident +false +0 +false +List + +2 +i18233/i18233.scala + +Foo$ +Object +.Foo$ +render +59 +65 +4 +refArrayOps +Apply +false +0 +false +values + +3 +i18233/i18233.scala + +Foo$ +Object +.Foo$ +render +59 +70 +4 +tail +Select +false +0 +false +values.tail + +4 +i18233/i18233.scala + +Foo$ +Object +.Foo$ +render +54 +81 +4 +mkString +Select +false +0 +false +List(values.tail*).mkString + +5 +i18233/i18233.scala + +Foo$ +Object +.Foo$ +render +41 +51 +4 +render +DefDef +false +0 +false +def render + +6 +i18233/i18233.scala + +Test$ +Object +.Test$ + +111 +130 +7 +println +Apply +false +0 +false +println(Foo.render) + +7 +i18233/i18233.scala + +Test$ +Object +.Test$ + +119 +129 +7 +render +Select +false +0 +false +Foo.render +