scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.84k stars 1.05k forks source link

Crash related to XML in given #15574

Open kavedaa opened 2 years ago

kavedaa commented 2 years ago

Compiler version

3.0.0, 3.1.0, 3.1.2, 3.2.0-RC1

Minimized code

libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "2.1.0"
trait Renderer[A]:
  def render(x: A): xml.Elem

given Renderer[Int] with
  def render(x: Int) = <td>{ x.toString }</td>

Output (click arrow to expand)

```scala error while checking extends Renderer[Int] { def render(x: Int) = { { new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope, false , { val $buf = new _root_.scala.xml.NodeBuffer() $buf.&+( { x.toString } ) $buf }* ) } } } ```
prolativ commented 2 years ago

@kavedaa I cannot reproduce the issue - it compiles for me without any problems

kavedaa commented 2 years ago

I'm not able to make it compile without crashing.

Here is the complete output if that helps:

error while checking  extends Renderer[Int] {
  def render(x: Int) =
    {
      {
        new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope,
          false
        ,
          {
            val $buf = new _root_.scala.xml.NodeBuffer()
            $buf.&+(
              {
                x.toString
              }
            )
            $buf
          }*
        )
      }
    }
}
error while checking given object extends Renderer[Int] {
  def render(x: Int) =
    {
      {
        new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope,
          false
        ,
          {
            val $buf = new _root_.scala.xml.NodeBuffer()
            $buf.&+(
              {
                x.toString
              }
            )
            $buf
          }*
        )
      }
    }
}
error while checking package test {
  trait Renderer[A] {
    def render(x: A): xml.Elem
  }
  given object extends Renderer[Int] {
    def render(x: Int) =
      {
        {
          new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope,
            false
          ,
            {
              val $buf = new _root_.scala.xml.NodeBuffer()
              $buf.&+(
                {
                  x.toString
                }
              )
              $buf
            }*
          )
        }
      }
  }
}
[info] exception occurred while parser E:\prog\jvm\scala\bugs\html-util\src\main\scala\table.scala
[info] exception occurred while compiling E:\prog\jvm\scala\bugs\html-util\src\main\scala\table.scala
java.lang.AssertionError: assertion failed: position error, parent span does not contain child span
parent      =  extends Renderer[Int] {
  def render(x: Int) =
    {
      {
        new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope,
          false
        ,
          {
            val $buf = new _root_.scala.xml.NodeBuffer()
            $buf.&+(
              {
                x.toString
              }
            )
            $buf
          }*
        )
      }
    }
} # -1,
parent span = <74..141>,
child       = def render(x: Int) =
  {
    {
      new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope, false
        ,
      {
        val $buf = new _root_.scala.xml.NodeBuffer()
        $buf.&+(
          {
            x.toString
          }
        )
        $buf
      }*
      )
    }
  } # -1,
child span  = [97..101..142] while compiling E:\prog\jvm\scala\bugs\html-util\src\main\scala\table.scala
[error] ## Exception when compiling 1 sources to E:\prog\jvm\scala\bugs\html-util\target\scala-3.1.2\classes
[error] java.lang.AssertionError: assertion failed: position error, parent span does not contain child span
[error] parent      =  extends Renderer[Int] {
[error]   def render(x: Int) =
[error]     {
[error]       {
[error]         new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope,
[error]           false
[error]         ,
[error]           {
[error]             val $buf = new _root_.scala.xml.NodeBuffer()
[error]             $buf.&+(
[error]               {
[error]                 x.toString
[error]               }
[error]             )
[error]             $buf
[error]           }*
[error]         )
[error]       }
[error]     }
[error] } # -1,
[error] parent span = <74..141>,
[error] child       = def render(x: Int) =
[error]   {
[error]     {
[error]       new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope, false
[error]         ,
[error]       {
[error]         val $buf = new _root_.scala.xml.NodeBuffer()
[error]         $buf.&+(
[error]           {
[error]             x.toString
[error]           }
[error]         )
[error]         $buf
[error]       }*
[error]       )
[error]     }
[error]   } # -1,
[error] child span  = [97..101..142]
[error] scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[error] dotty.tools.dotc.ast.Positioned.check$1(Positioned.scala:175)
[error] dotty.tools.dotc.ast.Positioned.check$1$$anonfun$3(Positioned.scala:205)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.immutable.List.foreach(List.scala:333)
[error] dotty.tools.dotc.ast.Positioned.check$1(Positioned.scala:205)
[error] dotty.tools.dotc.ast.Positioned.checkPos(Positioned.scala:226)
[error] dotty.tools.dotc.ast.Positioned.check$1(Positioned.scala:200)
[error] dotty.tools.dotc.ast.Positioned.checkPos(Positioned.scala:226)
[error] dotty.tools.dotc.ast.Positioned.check$1(Positioned.scala:200)
[error] dotty.tools.dotc.ast.Positioned.check$1$$anonfun$3(Positioned.scala:205)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.immutable.List.foreach(List.scala:333)
[error] dotty.tools.dotc.ast.Positioned.check$1(Positioned.scala:205)
[error] dotty.tools.dotc.ast.Positioned.checkPos(Positioned.scala:226)
[error] dotty.tools.dotc.parsing.Parser.parse$$anonfun$1(ParserPhase.scala:40)
[error] dotty.tools.dotc.core.Phases$Phase.monitor(Phases.scala:411)
[error] dotty.tools.dotc.parsing.Parser.parse(ParserPhase.scala:41)
[error] dotty.tools.dotc.parsing.Parser.runOn$$anonfun$1(ParserPhase.scala:50)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.immutable.List.foreach(List.scala:333)
[error] dotty.tools.dotc.parsing.Parser.runOn(ParserPhase.scala:50)
[error] dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:259)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1328)
[error] dotty.tools.dotc.Run.runPhases$1(Run.scala:270)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:278)
[error] scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
[error] dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68)
[error] dotty.tools.dotc.Run.compileUnits(Run.scala:287)
[error] dotty.tools.dotc.Run.compileSources(Run.scala:220)
[error] dotty.tools.dotc.Run.compile(Run.scala:204)
[error] dotty.tools.dotc.Driver.doCompile(Driver.scala:39)
[error] dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:88)
[error] dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
[error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:192)
[error] scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
[error] sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:247)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:182)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4$adapted(MixedAnalyzingCompiler.scala:163)
[error] sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:239)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:163)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:210)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:528)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:528)
[error] sbt.internal.inc.Incremental$.$anonfun$apply$5(Incremental.scala:175)
[error] sbt.internal.inc.Incremental$.$anonfun$apply$5$adapted(Incremental.scala:173)
[error] sbt.internal.inc.Incremental$$anon$2.run(Incremental.scala:459)
[error] sbt.internal.inc.IncrementalCommon$CycleState.next(IncrementalCommon.scala:116)
[error] sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:56)
[error] sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:52)
[error] sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:263)
[error] sbt.internal.inc.Incremental$.$anonfun$incrementalCompile$8(Incremental.scala:414)
[error] sbt.internal.inc.Incremental$.withClassfileManager(Incremental.scala:501)
[error] sbt.internal.inc.Incremental$.incrementalCompile(Incremental.scala:401)
[error] sbt.internal.inc.Incremental$.apply(Incremental.scala:167)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:528)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:482)
[error] sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:332)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:420)
[error] sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:137)
[error] sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:2357)
[error] sbt.Defaults$.$anonfun$compileIncrementalTask$2(Defaults.scala:2314)
[error] sbt.internal.io.Retry$.apply(Retry.scala:46)
[error] sbt.internal.io.Retry$.apply(Retry.scala:28)
[error] sbt.internal.io.Retry$.apply(Retry.scala:23)
[error] sbt.internal.server.BspCompileTask$.compute(BspCompileTask.scala:31)
[error] sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:2310)
[error] scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error] sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error] sbt.std.Transform$$anon$4.work(Transform.scala:68)
[error] sbt.Execute.$anonfun$submit$2(Execute.scala:282)
[error] sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
[error] sbt.Execute.work(Execute.scala:291)
[error] sbt.Execute.$anonfun$submit$1(Execute.scala:282)
[error] sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error] sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
[error] java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error] java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error] java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error] java.lang.Thread.run(Thread.java:748)
[error]
[error] stack trace is suppressed; run last Compile / compileIncremental for the full output
[error] (Compile / compileIncremental) java.lang.AssertionError: assertion failed: position error, parent span does not contain child span
[error] parent      =  extends Renderer[Int] {
[error]   def render(x: Int) =
[error]     {
[error]       {
[error]         new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope,
[error]           false
[error]         ,
[error]           {
[error]             val $buf = new _root_.scala.xml.NodeBuffer()
[error]             $buf.&+(
[error]               {
[error]                 x.toString
[error]               }
[error]             )
[error]             $buf
[error]           }*
[error]         )
[error]       }
[error]     }
[error] } # -1,
[error] parent span = <74..141>,
[error] child       = def render(x: Int) =
[error]   {
[error]     {
[error]       new _root_.scala.xml.Elem(null, "td", _root_.scala.xml.Null, $scope, false
[error]         ,
[error]       {
[error]         val $buf = new _root_.scala.xml.NodeBuffer()
[error]         $buf.&+(
[error]           {
[error]             x.toString
[error]           }
[error]         )
[error]         $buf
[error]       }*
[error]       )
[error]     }
[error]   } # -1,
[error] child span  = [97..101..142]
prolativ commented 2 years ago

Maybe there's something specific to your setup of the project? Could you put it into a cloneable repository? Alternatively can you reproduce it using scala-cli or scastie? I've put the code into a gist https://gist.github.com/prolativ/44d4a0216389835e3325044d197395a5 and I can successfully compile it with scala-cli

scala-cli compile https://gist.github.com/prolativ/44d4a0216389835e3325044d197395a5

Does this work for you?

kavedaa commented 2 years ago

Cloneable repo here: https://github.com/kavedaa/html-util-temp.git

som-snytt commented 2 years ago

The off-by-one span error on Windows suggests maybe lineSeparator is involved, as it adds a CR to NL?

It works for me under WSL Ubuntu; I'm much too lazy to try it under bare Windows. Or rather, my instinct for self-preservation is just strong enough.

(For other newbies, I see the position check at parser is compile-time true, not a compiler option.)

prolativ commented 2 years ago

Maybe this is indeed something related to Windows. The cloned repo compiles perfectly fine for me on Mac. @kavedaa have you tried running the code with scastie and scala-cli as I asked you?

som-snytt commented 2 years ago

Good morning, I realized I updated my cygwin during pandemic for a Scala 2 bug, and it was easy to do a quick clone and verify the behavior.

Just noticed I also have a dotty repo, apparently I tweaked virtual SourceFile last April for Windows behavior.

som-snytt commented 2 years ago

Why I avoid this path (so to speak):

$ ./bin/scalac -version
./bin/scalac: line 2: $'\r': command not found
./bin/scalac: line 4: $'\r': command not found
/bin/common: No such file or directoryects/dotty/bin/..

I already paid the ante to google sbt -no-colors, though there is still some prompt noise:

←[?1h←=←[?2004hsbt:html-util>
←[?1l←>←[?1000l←[?2004l←[?1h←=←[?2004hsbt:html-util> exit
←[?1l←>←[?1000l←[?2004l[info] shutting down sbt server

in case someone knows the quick workaround, or "quirkaround" would be the portmanteau.

I say I avoid putting myself in this situation, but I will take a look at this. How hard could it be?

som-snytt commented 2 years ago

This is (duplicates) https://github.com/scala/bug/issues/10321 fixed as https://github.com/scala/scala/pull/7330

There are a couple of position fixes which I'll try to forward port.

The new ungrokable error is

[error] -- Error: .../snips/i15574/html-util-temp/src/main/scala/table.scala:3:14
[error] 3 |trait Renderer[A]:
[error]   |              ^
[error]   |Could not read definition of package object package$package in .../.cache/coursier/v1/https/scala-webapps.epfl.ch/artifactory/central/org/scala-lang/scala3-library_3/3.0.2/scala3-library_3-3.0.2.jar(scala/compiletime/package$package.class)
[error]   |An exception was encountered:
[error]   |  java.lang.ClassCastException: class dotty.tools.dotc.core.Symbols$NoSymbol$ cannot be cast to class dotty.tools.dotc.core.Symbols$ClassSymbol (dotty.tools.dotc.core.Symbols$NoSymbol$ and dotty.tools.dotc.core.Symbols$ClassSymbol are in unnamed module of loader sbt.internal.classpath.ClassLoaderCache$Key$CachedClassLoader @1301f9a4)
[error]   |Run with -Ydebug-unpickling to see full stack trace.
hartmut27 commented 2 years ago

i've had the error message position error, parent span does not contain child span. In my case, there was no <td> e.g. in the sourcecode. But there where | and > forming a graphical |> pipesymbol. I replaced the two characters with the offical pipe (and tap) functions. Then the error message disappeared. My guess is > chars in sourcecode make trouble somehow?

Ref.: ID_MR5SC5WR8WSF

som-snytt commented 2 years ago

The problem seems to be https://github.com/lampepfl/dotty/pull/15635/files#diff-052bd0d14090dbcf9a970757f11efe267009ee324696dcc3ea785c32eafc770cR77

which is corrected in https://github.com/lampepfl/dotty/pull/15635

It looks like the scala 2 fixes to locate the start of the element are simplified in scala 3, which tracks lastCharOffset.

This would be an example of unfortunate duplicative effort. How many versions of CharArrayReader does one need?

Another divergence is due to \u unicode escape handling. If diffing and porting, it's nicer for diffs to remain small; the gold standard is still just to share utility code.