scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

Position failure under Bloop with small source file #12981

Open som-snytt opened 1 month ago

som-snytt commented 1 month ago

Questions are not bug reports

"What the -- ??"

Reproduction steps

Scala version: 2.13.13

class Escapes { s"""aaa \s bbb""" }

Problem

Correctly errors with

scala-cli compile --scala 2.13.13 --verbose --server=false short.scala

but crashes under Bloop.

Observed at https://github.com/scala/scala3/issues/20110

➜  bin ./scala-cli --version
Scala CLI version: 1.2.1
Scala version (default): 3.4.1
➜  bin cd
➜  ~ cd snips
➜  snips scala-cli compile --scala 2.13.13 short.scala
Downloading compilation server 1.5.16-sc-1
Starting compilation server
Compiling project (Scala 2.13.13, JVM (21))
Error compiling project (Scala 2.13.13, JVM (21))
Error: Unexpected error when compiling snips_e8caf7c7ca-2d67b5d8d6: java.lang.IndexOutOfBoundsException: 37
        at scala.reflect.internal.util.BatchSourceFile.offsetToLine(SourceFile.scala:213)
        at scala.tools.xsbt.DelegatingReporter$.makePosition$1(DelegatingReporter.scala:137)
        at scala.tools.xsbt.DelegatingReporter$.convert(DelegatingReporter.scala:190)
        at scala.tools.xsbt.DelegatingReporter.doReport(DelegatingReporter.scala:225)
        at scala.reflect.internal.Reporter.filteredInfo(Reporting.scala:126)
        at scala.reflect.internal.Reporter.error(Reporting.scala:121)
        at scala.tools.nsc.Reporting$PerRunReporting.error(Reporting.scala:377)
        at scala.tools.nsc.typechecker.Contexts$ImmediateReporter.error(Contexts.scala:1875)
        at scala.tools.nsc.typechecker.Contexts$ContextReporter.errorAndDumpIfDebug(Contexts.scala:1752)
        at scala.tools.nsc.typechecker.Contexts$Context.error(Contexts.scala:824)
        at scala.tools.nsc.typechecker.ContextErrors$TyperContextErrors$TyperErrorGen$.macroExpansionError(ContextErrors.scala:943)
        at scala.tools.nsc.typechecker.ContextErrors$TyperContextErrors$TyperErrorGen$.MacroGeneratedAbort(ContextErrors.scala:969)
        at scala.tools.nsc.typechecker.Macros.macroExpandWithRuntime(Macros.scala:817)
        at scala.tools.nsc.typechecker.Macros.macroExpandWithRuntime$(Macros.scala:772)
        at scala.tools.nsc.Global$$anon$6.macroExpandWithRuntime(Global.scala:512)
        at scala.tools.nsc.typechecker.Macros$MacroExpander.$anonfun$expand$2(Macros.scala:601)
        at scala.tools.nsc.Global.withInfoLevel(Global.scala:255)
        at scala.tools.nsc.typechecker.Macros$MacroExpander.expand(Macros.scala:594)
        at scala.tools.nsc.typechecker.Macros$MacroExpander.apply(Macros.scala:556)
        at scala.tools.nsc.typechecker.Macros.standardMacroExpand(Macros.scala:757)
        at scala.tools.nsc.typechecker.Macros.standardMacroExpand$(Macros.scala:755)
        at scala.tools.nsc.Global$$anon$6.standardMacroExpand(Global.scala:512)
        at scala.tools.nsc.typechecker.AnalyzerPlugins$$anon$11.default(AnalyzerPlugins.scala:474)
        at scala.tools.nsc.typechecker.AnalyzerPlugins$$anon$11.default(AnalyzerPlugins.scala:471)
        at scala.tools.nsc.typechecker.AnalyzerPlugins.invoke(AnalyzerPlugins.scala:428)
        at scala.tools.nsc.typechecker.AnalyzerPlugins.pluginsMacroExpand(AnalyzerPlugins.scala:471)
        at scala.tools.nsc.typechecker.AnalyzerPlugins.pluginsMacroExpand$(AnalyzerPlugins.scala:471)
        at scala.tools.nsc.Global$$anon$6.pluginsMacroExpand(Global.scala:512)
        at scala.tools.nsc.typechecker.Macros.macroExpand(Macros.scala:746)
        at scala.tools.nsc.typechecker.Macros.macroExpand$(Macros.scala:739)
        at scala.tools.nsc.Global$$anon$6.macroExpand(Global.scala:512)
        at scala.tools.nsc.typechecker.Typers$Typer.vanillaAdapt$1(Typers.scala:1281)
        at scala.tools.nsc.typechecker.Typers$Typer.adapt(Typers.scala:1352)
        at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:6264)
        at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:6327)
        at scala.tools.nsc.typechecker.Typers$Typer.$anonfun$typedStats$9(Typers.scala:3529)
        at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:3529)
        at scala.tools.nsc.typechecker.Typers$Typer.typedTemplate(Typers.scala:2134)
        at scala.tools.nsc.typechecker.Typers$Typer.typedClassDef(Typers.scala:1972)
        at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:6156)
        at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:6249)
        at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:6327)
        at scala.tools.nsc.typechecker.Typers$Typer.$anonfun$typedStats$9(Typers.scala:3529)
        at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:3529)
        at scala.tools.nsc.typechecker.Typers$Typer.typedPackageDef$1(Typers.scala:5836)
        at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:6159)
        at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:6249)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$TyperPhase.apply(Analyzer.scala:125)
        at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:481)
        at scala.tools.nsc.typechecker.Analyzer$typerFactory$TyperPhase.run(Analyzer.scala:112)
        at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1549)
        at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1533)
        at scala.tools.nsc.Global$Run.compileSources(Global.scala:1525)
        at scala.tools.nsc.Global$Run.compileFiles(Global.scala:1638)
        at scala.tools.xsbt.CachedCompiler0.run(CompilerBridge.scala:176)
        at scala.tools.xsbt.CachedCompiler0.run(CompilerBridge.scala:139)
        at scala.tools.xsbt.CompilerBridge.run(CompilerBridge.scala:43)
        at sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
        at sbt.internal.inc.bloop.internal.BloopHighLevelCompiler.compileSources$1(BloopHighLevelCompiler.scala:133)
        at sbt.internal.inc.bloop.internal.BloopHighLevelCompiler.$anonfun$compile$7(BloopHighLevelCompiler.scala:159)
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
        at sbt.internal.inc.bloop.internal.BloopHighLevelCompiler.$anonfun$compile$1(BloopHighLevelCompiler.scala:71)
        at bloop.tracing.NoopTracer$.trace(BraveTracer.scala:53)
        at sbt.internal.inc.bloop.internal.BloopHighLevelCompiler.timed$1(BloopHighLevelCompiler.scala:70)
        at sbt.internal.inc.bloop.internal.BloopHighLevelCompiler.$anonfun$compile$6(BloopHighLevelCompiler.scala:159)
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
        at monix.eval.internal.TaskRunLoop$.startFull(TaskRunLoop.scala:81)
        at monix.eval.internal.TaskRestartCallback.syncOnSuccess(TaskRestartCallback.scala:101)
        at monix.eval.internal.TaskRestartCallback.onSuccess(TaskRestartCallback.scala:74)
        at monix.eval.internal.TaskExecuteOn$AsyncRegister$$anon$1.run(TaskExecuteOn.scala:71)
        at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1423)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)

Compilation failed
unkarjedy commented 1 month ago

This is a continuation of the discussion from https://github.com/scala/scala3/issues/20110

If you use compiler-based highlighting, you can see in the editor that a wrong range is reported:

In the end, even though plain scalac doesn't crash itself, it's still the one to blame as it seems. It returns strange problem range, which includes redundant characters in the end. The compiler doesn't crash by default because it doesn't use the range when reporting the error, but other tools do.

To check it with plain scalac I implemented a simple custom reporter:

import scala.reflect.internal.util.{CodeAction, Position}
import scala.tools.nsc.Settings
import scala.tools.nsc.reporters.FilteringReporter

class MyReporter(_settings: Settings) extends FilteringReporter {
  override def settings: Settings = _settings
  override def doReport(pos: Position, msg: String, severity: Severity, actions: List[CodeAction]): Unit =
    System.out.println(s"### [$severity] position: (${pos.start},${pos.end}), msg: $msg")
}

And then passed it to scalac:

cat src/main/scala/Main.scala
class Main {
  s"""aaa \s bbb"""
}%                                                                                                                                                                                
cat src/main/scala/Main.scala | wc -m
      34
scalac -Xreporter MyReporter -d . src/main/scala/Main.scala
### [ERROR] position: (23,36), msg: invalid escape '\s' not one of [\b, \t, \n, \f, \r, \\, \", \', \uxxxx] at index 4 in "aaa \s bbb". Use \\ for literal \.

Notice that file length is 34 but the range end offset is 36, which leads to IndexOutOfBoundsException in other tools, because none of them expect wrong ranges.

In order for my reporter to be detected by the compiler I had to patch JAVA_OPTS and add the class path with the reporter (untitled68/target/scala-2.13/classes) to -Xbootclasspatha/. I tried to use scala options like -bootclasspath/-classpath/-javabootclasspath but it didn't work for some reason.

echo $JAVA_OPTS
-Xbootclasspath/a:/Users/dmitrii.naumenko/Desktop/dev/debug/untitled68/target/scala-2.13/classes:/Users/dmitrii.naumenko/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.13.13/scala-reflect-2.13.13.jar:/Users/dmitrii.naumenko/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.13/scala-library-2.13.13.jar:/Users/dmitrii.naumenko/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.13.13/scala-compiler-2.13.13.jar