Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scalafmt errors on formatting code which returns a multi-argument tuple #3369

Closed
mdedetrich opened this issue Nov 11, 2022 · 0 comments · Fixed by #3380
Closed

Scalafmt errors on formatting code which returns a multi-argument tuple #3369

mdedetrich opened this issue Nov 11, 2022 · 0 comments · Fixed by #3380

Comments

@mdedetrich
Copy link
Contributor

Configuration (required)

Please paste the contents of your .scalafmt.conf file here:

version                                  = 3.6.1
runner.dialect                           = scala213
project.git                              = true
style                                    = defaultWithAlign
docstrings.style                         = Asterisk
docstrings.wrap                          = false
indentOperator.preset                    = spray
maxColumn                                = 120
lineEndings                              = preserve
rewrite.rules                            = [RedundantParens, SortImports, AvoidInfix]
indentOperator.exemptScope               = all
align.preset                             = some
align.tokens."+"                         = [
  {
    code   = "~>"
    owners = [
      { regex = "Term.ApplyInfix" }
    ]
  }
]
literals.hexDigits                       = upper
literals.hexPrefix                       = lower
binPack.unsafeCallSite                   = always
binPack.unsafeDefnSite                   = always
binPack.indentCallSiteSingleArg          = false
binPack.indentCallSiteOnce               = true
newlines.avoidForSimpleOverflow          = [slc]
newlines.source                          = keep
newlines.beforeMultiline                 = keep
align.openParenDefnSite                  = false
align.openParenCallSite                  = false
align.allowOverflow                      = true
optIn.breakChainOnFirstMethodDot         = false
optIn.configStyleArguments               = false
danglingParentheses.preset               = false
spaces.inImportCurlyBraces               = true
rewrite.neverInfix.excludeFilters        = [
  and
  min
  max
  until
  to
  by
  eq
  ne
  "should.*"
  "contain.*"
  "must.*"
  in
  ignore
  be
  taggedAs
  thrownBy
  synchronized
  have
  when
  size
  only
  noneOf
  oneElementOf
  noElementsOf
  atLeastOneElementOf
  atMostOneElementOf
  allElementsOf
  inOrderElementsOf
  theSameElementsAs
  theSameElementsInOrderAs
]
rewriteTokens          = {
  "⇒": "=>"
  "→": "->"
  "←": "<-"
}
project.layout         = StandardConvention

Command-line parameters (required)

When I run scalafmt via CLI like this: scalafmt

Steps

Given code like this:

object Test {
  private def streamProbesWithOffsetFactory(
      committerSettings: CommitterSettings
  ): (TestPublisher.Probe[Committable],
      Consumer.Control,
      TestSubscriber.Probe[CommittableOffsetBatch],
      TestOffsetFactory) = {
    val (source, control, sink) = streamProbes(committerSettings)
    val factory = TestOffsetFactory(new TestBatchCommitter(committerSettings))
    (source, control, sink, factory)
  }
}

Problem

Scalafmt errors out with the following message:

<@incubator-pekko-connectors-kafka>-<⎇ update-and-apply-scalafmt>-<±>-8-> scalafmt
org.scalafmt.cli.FailedToFormat: /Users/mdedetrich/github/incubator-pekko-connectors-kafka/tests/src/test/scala/akka/kafka/internal/CommitCollectorStageSpec.scala
Caused by: org.scalafmt.Error$PreciseIncomplete: /Users/mdedetrich/github/incubator-pekko-connectors-kafka/tests/src/test/scala/akka/kafka/internal/CommitCollectorStageSpec.scala:4: error: Unable to format file due to bug in scalafmt
  ): (TestPublisher.Probe[Committable],
                                      ^
        at org.scalafmt.Scalafmt$.$anonfun$doFormatOne$7(Scalafmt.scala:161)
        at scala.util.Success.flatMap(Try.scala:258)
        at org.scalafmt.Scalafmt$.$anonfun$doFormatOne$4(Scalafmt.scala:156)
        at scala.meta.parsers.Parsed.fold(Errors.scala:12)
        at scala.meta.parsers.Parsed.fold$(Errors.scala:11)
        at scala.meta.parsers.Parsed$Success.fold(Errors.scala:26)
        at org.scalafmt.Scalafmt$.org$scalafmt$Scalafmt$$doFormatOne(Scalafmt.scala:152)
        at org.scalafmt.Scalafmt$.doFormat(Scalafmt.scala:126)
        at org.scalafmt.Scalafmt$.formatCodeWithStyle(Scalafmt.scala:91)
        at org.scalafmt.Scalafmt$.$anonfun$formatCode$3(Scalafmt.scala:78)
        at scala.util.Success.fold(Try.scala:281)
        at org.scalafmt.Scalafmt$.formatCode(Scalafmt.scala:78)
        at org.scalafmt.Scalafmt$.format(Scalafmt.scala:59)
        at org.scalafmt.Scalafmt.format(Scalafmt.scala)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:578)
        at org.scalafmt.dynamic.ScalafmtReflect.$anonfun$tryFormat$1(ScalafmtReflect.scala:121)
        at scala.util.Try$.apply(Try.scala:210)
        at org.scalafmt.dynamic.ScalafmtReflect.tryFormat(ScalafmtReflect.scala:117)
        at org.scalafmt.dynamic.ScalafmtReflectConfig.tryFormat(ScalafmtReflectConfig.scala:95)
        at org.scalafmt.dynamic.ScalafmtDynamicSession.$anonfun$tryForceFormat$1(ScalafmtDynamicSession.scala:49)
        at scala.util.Success.flatMap(Try.scala:258)
        at org.scalafmt.dynamic.ScalafmtDynamicSession.tryForceFormat(ScalafmtDynamicSession.scala:49)
        at org.scalafmt.dynamic.ScalafmtDynamicSession.tryFormat(ScalafmtDynamicSession.scala:36)
Reformatat org.scalafmt.dynamic.ScalafmtDynamicSession.format(ScalafmtDynamicSession.scala:18)
   83,0%at org.scalafmt.cli.ScalafmtDynamicRunner$.handleFile(ScalafmtDynamicRunner.scala:76)
        at org.scalafmt.cli.ScalafmtDynamicRunner$.$anonfun$run$7(ScalafmtDynamicRunner.scala:49)
        at org.scalafmt.cli.ScalafmtDynamicRunner$.$anonfun$run$7$adapted(ScalafmtDynamicRunner.scala:47)
        at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:563)
        at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:561)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1293)
        at scala.collection.parallel.ParIterableLike$Foreach.leaf(ParIterableLike.scala:938)
        at scala.collection.parallel.Task.$anonfun$tryLeaf$1(Tasks.scala:52)
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
        at scala.util.control.Breaks$$anon$1.catchBreak(Breaks.scala:97)
        at scala.collection.parallel.Task.tryLeaf(Tasks.scala:55)
        at scala.collection.parallel.Task.tryLeaf$(Tasks.scala:49)
        at scala.collection.parallel.ParIterableLike$Foreach.tryLeaf(ParIterableLike.scala:935)
        at scala.collection.parallel.AdaptiveWorkStealingTasks$AWSTWrappedTask.internal(Tasks.scala:159)
        at scala.collection.parallel.AdaptiveWorkStealingTasks$AWSTWrappedTask.internal$(Tasks.scala:156)
        at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$AWSFJTWrappedTask.internal(Tasks.scala:304)
        at scala.collection.parallel.AdaptiveWorkStealingTasks$AWSTWrappedTask.compute(Tasks.scala:149)
        at scala.collection.parallel.AdaptiveWorkStealingTasks$AWSTWrappedTask.compute$(Tasks.scala:148)
        at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$AWSFJTWrappedTask.compute(Tasks.scala:304)
        at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:194)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
a.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1311)
   84,2%at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1840)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1806)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)

Expectation

Scalafmt doesn't crash with an error.

Workaround

The core problem appears to be specifically the function returning a tuple that contains multiple arguments. If we change the function to

object Test {
  private def streamProbesWithOffsetFactory(
      committerSettings: CommitterSettings
  ): (TestPublisher.Probe[Committable]) = {
    val (source, control, sink) = streamProbes(committerSettings)
    val factory = TestOffsetFactory(new TestBatchCommitter(committerSettings))
    (source, control, sink, factory)
  }
}

Then it formats without problems. Having 2 arguments in the return tuple is enough for scalafmt to throw an error

Notes

This code block was originally part of a larger source file, see https://github.com/apache/incubator-pekko-connectors-kafka/blob/e40e9e7c5ec0986103a834d2514394d7eb488978/tests/src/test/scala/akka/kafka/internal/CommitCollectorStageSpec.scala#L407-L416. When scalafmt is run on this file you get a search state exploded error which seems to be hiding the original error, this due to the fact that when scalafmt is run on the larger source file, adjusting runner.maxStateVisits or runner.optimizer.maxVisitsPerToken never actually solves the problem even with ridiculously large values.

@mdedetrich mdedetrich changed the title Scalafmt errors on formatting code which returns a multi-art tuple Scalafmt errors on formatting code which returns a multi-argument tuple Nov 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant