scalameta / metals

Scala language server with rich IDE features 🚀
https://scalameta.org/metals/
Apache License 2.0
2.1k stars 333 forks source link

Metals server crashes when typing $ in string interpolation #6808

Closed Florian3k closed 1 month ago

Florian3k commented 1 month ago

Describe the bug

Reproduction repository (scala3 fork): https://github.com/Florian3k/scala3/tree/metals-crash-repro Switch build server to sbt In file scaladoc/src/dotty/tools/scaladoc/tasty/SymOps.scala put cursor in line 84 at column 87 Type " (two " should appear) and then $ Metals server crashes with:

[Error - 2:03:33 PM] Request textDocument/codeAction failed.
  Message: Internal error.
  Code: -32603 
org.scalameta.UnreachableError: this code path should've been unreachable
where curr = {token = 1007, position = [3436,3445), strVal = ", res: ", base = 10}

    at org.scalameta.UnreachableError$.raise(UnreachableError.scala:20)
    at org.scalameta.UnreachableError$.raise(UnreachableError.scala:8)
    at scala.meta.internal.tokenizers.ScalametaTokenizer.getToken(ScalametaTokenizer.scala:299)
    at scala.meta.internal.tokenizers.ScalametaTokenizer.emitContents$1(ScalametaTokenizer.scala:79)
    at scala.meta.internal.tokenizers.ScalametaTokenizer.emitTokenInterpolation$1(ScalametaTokenizer.scala:94)
    at scala.meta.internal.tokenizers.ScalametaTokenizer.emitToken$1(ScalametaTokenizer.scala:144)
    at scala.meta.internal.tokenizers.ScalametaTokenizer.loop$1(ScalametaTokenizer.scala:152)
    at scala.meta.internal.tokenizers.ScalametaTokenizer.uncachedTokenize(ScalametaTokenizer.scala:162)
    at scala.meta.internal.tokenizers.ScalametaTokenizer.$anonfun$tokenize$1(ScalametaTokenizer.scala:16)
    at scala.collection.concurrent.TrieMap.getOrElseUpdate(TrieMap.scala:960)
    at scala.meta.internal.tokenizers.ScalametaTokenizer.tokenize(ScalametaTokenizer.scala:16)
    at scala.meta.internal.tokenizers.ScalametaTokenizer$$anon$1.apply(ScalametaTokenizer.scala:313)
    at scala.meta.tokenizers.Api$XtensionTokenizeDialectInput.tokenize(Api.scala:22)
    at scala.meta.internal.metals.codeactions.StringActions.$anonfun$contribute$1(StringActions.scala:36)
    at scala.Option.flatMap(Option.scala:283)
    at scala.meta.internal.metals.codeactions.StringActions.contribute(StringActions.scala:35)
    at scala.meta.internal.metals.codeactions.CodeActionProvider$$anonfun$1.applyOrElse(CodeActionProvider.scala:73)
    at scala.meta.internal.metals.codeactions.CodeActionProvider$$anonfun$1.applyOrElse(CodeActionProvider.scala:71)
    at scala.collection.immutable.List.collect(List.scala:276)
    at scala.meta.internal.metals.codeactions.CodeActionProvider.codeActions(CodeActionProvider.scala:71)
    at scala.meta.internal.metals.MetalsLspService.$anonfun$codeAction$1(MetalsLspService.scala:1207)
    at scala.meta.internal.metals.CancelTokens$.future(CancelTokens.scala:38)
    at scala.meta.internal.metals.MetalsLspService.codeAction(MetalsLspService.scala:1206)
    at scala.meta.internal.metals.WorkspaceLspService.codeAction(WorkspaceLspService.scala:525)
    at scala.meta.metals.lsp.DelegatingScalaService.codeAction(DelegatingScalaService.scala:146)
    at jdk.internal.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint.lambda$recursiveFindRpcMethods$0(GenericEndpoint.java:65)
    at org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint.request(GenericEndpoint.java:128)
    at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.handleRequest(RemoteEndpoint.java:271)
    at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.consume(RemoteEndpoint.java:201)
    at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.handleMessage(StreamMessageProducer.java:185)
    at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:97)
    at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:114)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:840)

Expected behavior

Doesn't crash

Operating system

macOS

Editor/Extension

VS Code

Version of Metals

1.3.5+142-fe3dc071-SNAPSHOT

Extra context or search terms

No response

Florian3k commented 1 month ago

Minimized reproduction:

@main def main() =
    println(s""" ${1}  ${2} """)

Put cursor in the middle, between two spaces and type " and $

[Error - 3:00:28 PM] Request textDocument/codeAction failed.
  Message: Internal error.
  Code: -32603 
org.scalameta.UnreachableError: this code path should've been unreachable
where curr = {token = 1007, position = [43,45), strVal = " , base = 10}