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

SearchStateExploded exception #1527

Closed
poslegm opened this issue Oct 12, 2019 · 4 comments · Fixed by #1836
Closed

SearchStateExploded exception #1527

poslegm opened this issue Oct 12, 2019 · 4 comments · Fixed by #1836
Labels

Comments

@poslegm
Copy link
Collaborator

poslegm commented Oct 12, 2019

This template is a guideline, not a strict requirement.

  • Version: 2.1.1
  • Integration: anything
  • Configuration:
version = 2.1.1

Steps

Given code like this:

object a {
@tailrec
  final def rhsOptimalToken(start: FormatToken): Token = start.right match {
      case T.Comma() | T.LeftParen() | T.RightParen() | T.RightBracket() |
          T.Semicolon() | T.RightArrow() | T.Equals()
          if next(start) != start &&
            !startsNewBlock(start.right) &&
            newlinesBetween(start.between) == 0 =>
        rhsOptimalToken(next(start))
      case _ => start.left
    }
}

When I run scalafmt like this:

scalafmt --stdin

Problem

Scalafmt formats code like this:

org.scalafmt.cli.FailedToFormat: stdin.scala
Caused by: org.scalafmt.Error$SearchStateExploded: Search state exploded around line 6
        at org.scalafmt.internal.BestFirstSearch.shortestPath(BestFirstSearch.scala:219)
        at org.scalafmt.internal.BestFirstSearch.getBestPath(BestFirstSearch.scala:277)
        at org.scalafmt.Scalafmt$.format(Scalafmt.scala:63)
        at org.scalafmt.cli.ScalafmtCoreRunner$.unsafeHandleFile(ScalafmtCoreRunner.scala:85)
        at org.scalafmt.cli.ScalafmtCoreRunner$.handleFile(ScalafmtCoreRunner.scala:64)
        at org.scalafmt.cli.ScalafmtCoreRunner$.$anonfun$run$3(ScalafmtCoreRunner.scala:42)
        at org.scalafmt.cli.ScalafmtCoreRunner$.$anonfun$run$3$adapted(ScalafmtCoreRunner.scala:41)
        at scala.collection.Iterator.foreach(Iterator.scala:941)
        at scala.collection.Iterator.foreach$(Iterator.scala:941)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1429)
        at scala.collection.parallel.ParIterableLike$Foreach.leaf(ParIterableLike.scala:974)
        at scala.collection.parallel.Task.$anonfun$tryLeaf$1(Tasks.scala:53)
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
        at scala.util.control.Breaks$$anon$1.catchBreak(Breaks.scala:67)
        at scala.collection.parallel.Task.tryLeaf(Tasks.scala:56)
        at scala.collection.parallel.Task.tryLeaf$(Tasks.scala:50)
        at scala.collection.parallel.ParIterableLike$Foreach.tryLeaf(ParIterableLike.scala:971)
        at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.compute(Tasks.scala:153)
        at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.compute$(Tasks.scala:149)
        at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.compute(Tasks.scala:440)
        at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)

Expectation

Scalafmt doesn't fail

Notes

Braces around function body solves the issue:

object a {
 @tailrec
  final def rhsOptimalToken(start: FormatToken): Token = {
    start.right match {
      case T.Comma() | T.LeftParen() | T.RightParen() | T.RightBracket() | T.Semicolon() |
           T.RightArrow() | T.Equals()
          if next(start) != start &&
            !startsNewBlock(start.right) &&
            newlinesBetween(start.between) == 0 =>
        rhsOptimalToken(next(start))
      case _ => start.left
    }
  }
}

And this code formats fine:

object a {
@tailrec
  final def rhsOptimalToken(start: FormatToken): Token = start.right match {
      case Comma() | LeftParen() | RightParen() | RightBracket() |
          Semicolon() | RightArrow() | Equals()
          if next(start) != start &&
            !startsNewBlock(start.right) &&
            newlinesBetween(start.between) == 0 =>
        rhsOptimalToken(next(start))
      case _ => start.left
    }
}
@yoohaemin
Copy link

I just hit the exact same problem, thank you @poslegm for the workaround.

@poslegm poslegm added the bug label Oct 17, 2019
@ekrich
Copy link

ekrich commented Oct 31, 2019

Here is an additional file that won't format from Scala Native. This has not formatted for as long as I can remember. Using 2.2.1 at this time.

$ scripts/scalafmt
org.scalafmt.cli.FailedToFormat: /Users/eric/workspace/scala-native/nscplugin/src/main/scala/scala/scalanative/nscplugin/NirGenExpr.scala
Caused by: org.scalafmt.Error$SearchStateExploded: Search state exploded around line 1271

@ekrich
Copy link

ekrich commented Feb 21, 2020

Also, this previously in 1.5.1 was a Warning with no stack trace which I think is more appropriate if the user does not have much control over the error/warning.

[warn] Error in /home/travis/build/scala-native/scala-native/nscplugin/src/main/scala/scala/scalanative/nscplugin/NirGenExpr.scala: 
org.scalafmt.Error$SearchStateExploded: Search state exploded around line 1271

@poslegm
Copy link
Collaborator Author

poslegm commented Mar 28, 2020

Looks like it works fine on master. Will see after 2.5.0-RC1 release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants