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

Scala.js: Concatenating a Char and String causes assertion failure #13518

Closed
edwardcwang opened this issue Sep 14, 2021 · 2 comments
Closed

Scala.js: Concatenating a Char and String causes assertion failure #13518

edwardcwang opened this issue Sep 14, 2021 · 2 comments

Comments

@edwardcwang
Copy link

edwardcwang commented Sep 14, 2021

Compiler version

3.0.1

Minimized code

object FooBar {
  def baz(mySeq: Seq[String]) = mySeq.map(':' + _)
}

Output

java.lang.AssertionError: assertion failed
    scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:11)
    dotty.tools.backend.sjs.JSCodeGen.genStringConcat(JSCodeGen.scala:2487)
    dotty.tools.backend.sjs.JSCodeGen.genPrimitiveOp(JSCodeGen.scala:2098)
    dotty.tools.backend.sjs.JSCodeGen.genApply(JSCodeGen.scala:1712)
    dotty.tools.backend.sjs.JSCodeGen.genStatOrExpr(JSCodeGen.scala:1390)
    dotty.tools.backend.sjs.JSCodeGen.genExpr(JSCodeGen.scala:1263)
    dotty.tools.backend.sjs.JSCodeGen.genBody$1(JSCodeGen.scala:1146)
    dotty.tools.backend.sjs.JSCodeGen.genMethodDef(JSCodeGen.scala:1151)
    dotty.tools.backend.sjs.JSCodeGen.genMethodWithCurrentLocalNameScope$$anonfun$1(JSCodeGen.scala:1118)
    dotty.tools.backend.sjs.ScopedVar$.withScopedVars(ScopedVar.scala:35)
    dotty.tools.backend.sjs.JSCodeGen.genMethodWithCurrentLocalNameScope(JSCodeGen.scala:1124)
    dotty.tools.backend.sjs.JSCodeGen.genMethod$$anonfun$1(JSCodeGen.scala:1022)
    dotty.tools.backend.sjs.ScopedVar$.withScopedVars(ScopedVar.scala:35)
    dotty.tools.backend.sjs.JSCodeGen.genMethod(JSCodeGen.scala:1023)
    dotty.tools.backend.sjs.JSCodeGen.genScalaClass$$anonfun$2(JSCodeGen.scala:341)
    scala.collection.immutable.List.foreach(List.scala:333)
    dotty.tools.backend.sjs.JSCodeGen.genScalaClass(JSCodeGen.scala:346)
    dotty.tools.backend.sjs.JSCodeGen.genCompilationUnit$$anonfun$6$$anonfun$1(JSCodeGen.scala:217)
    dotty.tools.backend.sjs.ScopedVar$.withScopedVars(ScopedVar.scala:35)
    dotty.tools.backend.sjs.JSCodeGen.genCompilationUnit$$anonfun$2(JSCodeGen.scala:221)
    scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
    scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
    scala.collection.immutable.List.foreach(List.scala:333)
    dotty.tools.backend.sjs.JSCodeGen.genCompilationUnit(JSCodeGen.scala:223)
    dotty.tools.backend.sjs.JSCodeGen.run(JSCodeGen.scala:152)
    dotty.tools.backend.sjs.GenSJSIR.run(GenSJSIR.scala:15)
    dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:303)
    scala.collection.immutable.List.map(List.scala:246)
    dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:304)
    dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:205)
    scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
    scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
    scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
    dotty.tools.dotc.Run.runPhases$5(Run.scala:216)
    dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:224)
    scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
    dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
    dotty.tools.dotc.Run.compileUnits(Run.scala:231)
    dotty.tools.dotc.Run.compileSources(Run.scala:166)
    dotty.tools.dotc.Run.compile(Run.scala:150)
    dotty.tools.dotc.Driver.doCompile(Driver.scala:39)
    dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:88)
    dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
    sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
    sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:186)
    scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
    sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:241)
    sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:176)
    sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4$adapted(MixedAnalyzingCompiler.scala:157)
    sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:239)
    sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:157)
    sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:204)
    sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:528)
    sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:528)
    sbt.internal.inc.Incremental$.$anonfun$apply$5(Incremental.scala:174)
    sbt.internal.inc.Incremental$.$anonfun$apply$5$adapted(Incremental.scala:172)
    sbt.internal.inc.Incremental$$anon$2.run(Incremental.scala:457)
    sbt.internal.inc.IncrementalCommon$CycleState.next(IncrementalCommon.scala:116)
    sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:56)
    sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:52)
    sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:261)
    sbt.internal.inc.Incremental$.$anonfun$incrementalCompile$8(Incremental.scala:412)
    sbt.internal.inc.Incremental$.withClassfileManager(Incremental.scala:499)
    sbt.internal.inc.Incremental$.incrementalCompile(Incremental.scala:399)
    sbt.internal.inc.Incremental$.apply(Incremental.scala:166)
    sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:528)
    sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:482)
    sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:332)
    sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:420)
    sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:137)
    mill.scalalib.worker.ZincWorkerImpl.compileInternal(ZincWorkerImpl.scala:569)
    mill.scalalib.worker.ZincWorkerImpl.$anonfun$compileMixed0$1(ZincWorkerImpl.scala:357)
    mill.api.FixSizedCache.withCachedValue(FixSizedCache.scala:66)
    mill.scalalib.worker.ZincWorkerImpl.withCompilers(ZincWorkerImpl.scala:452)
    mill.scalalib.worker.ZincWorkerImpl.compileMixed0(ZincWorkerImpl.scala:356)
    mill.scalalib.worker.ZincWorkerImpl.compileMixed(ZincWorkerImpl.scala:324)
    mill.scalalib.ScalaModule.$anonfun$compile$2(ScalaModule.scala:170)
    mill.define.ApplyerGenerated.$anonfun$zipMap$9(ApplicativeGenerated.scala:21)
    mill.define.Task$MappedDest.evaluate(Task.scala:374)

Expectation

It should not crash with an assertion error. Worked around it by using only Strings: ":" + _

@sjrd
Copy link
Member

sjrd commented Sep 14, 2021

Thanks for the report. Could you please provide a more complete reproduction? Out of its context, ':' + _ means nothing, especially the _.

@edwardcwang
Copy link
Author

edwardcwang commented Sep 14, 2021

Thank you Sébastien for your fast reply! This was the more complete minimum reproduction I could get.

object FooBar {
  def baz(mySeq: Seq[String]) = mySeq.map(':' + _)
}

This also causes the crash for me:

object FooBar {
  def baz(mySeq: Seq[String]) = mySeq.map(i => ':' + i)
}

This also crashes:

object FooBar {
  def baz(mySeq: Seq[String], x: String) = 'a' + x
}

Weirdly enough, this doesn't crash...

object FooBar {
  def baz(mySeq: Seq[String]) = 'a' + "B"
}

edwardcwang added a commit to edwardcwang/scalatags that referenced this issue Sep 14, 2021
There is a bug in the dotty compiler? scala/scala3#13518

scalatags.js[3.0.1,1.7.0].compile java.lang.AssertionError: assertion failed
    scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:11)
    dotty.tools.backend.sjs.JSCodeGen.genStringConcat(JSCodeGen.scala:2487)
    dotty.tools.backend.sjs.JSCodeGen.genPrimitiveOp(JSCodeGen.scala:2098)
@sjrd sjrd changed the title ScalaJS: concatenating a Char and String causes assertion failure Scala.js: Concatenating a Char and String causes assertion failure Sep 15, 2021
sjrd added a commit to dotty-staging/dotty that referenced this issue Sep 15, 2021
Sometimes, the argument string's `tpe` can be `TermRef`, in which
case it is not directly a ref to `StringClass`. That was triggering
the assertion.

The assertions and the calls to `makePrimitiveBox` have actually
not been needed for a long time. The IR supports the arguments to a
`String_+` operator to be of any type. So we fix the issue by
removing all of that and directly emitting the `String_+`.
@sjrd sjrd closed this as completed in 33c335e Sep 16, 2021
sjrd added a commit that referenced this issue Sep 16, 2021
Fix #13518: Scala.js: fix primitive + string when the string is a TermRef.
lolgab added a commit to com-lihaoyi/scalatags that referenced this issue Dec 2, 2021
## Changes

* Add Mima to check how much we break binary compatibility.
* Update Mill to version `0.9.10` and fix build deprecations
* Add `scalaMajorVersion` in buildInfoMembers since Scala 3 represents types wrapped inside `()` in error messages.
* Explicitly apply implicit function `ev: A => Frag` in various implicit classes (like `SeqFrag`) since Scala 3 doesn't apply implicitly.
* Remove `protected[this] val RawFrag: Companion[RawFrag]` and `protected[this] val StringFrag: Companion[StringFrag]` since they break variance and Scala 3 is much less permissive with variance. Overriding them with strictier types in subclasses result in compiler errors. Since this was the only use case of `Companion` I removed it as well. Also I failed to  represent `Companion` in Scala 3 since it uses [different signatures for `unapply`](https://dotty.epfl.ch/docs/reference/changed-features/pattern-matching.html)
* Add explicit types to all `implicit` fields as required by Scala 3.
* Replace `def +(other: Any): String` in class `String` with String interpolator since it is not supported in Scala 3
* Make all abstract members in `Tags.scala`, `Tags2.scala` and `SvgTags.scala` `def`s instead of `val`s since Scala 3 doesn't support overriding an abstract `val` member with a `lazy val` as Scalatags does.
* Move the `SourceClasses` class and its companion object to the version specific code. Since it is the only code using macros.
* Updated tests to not use the `* -` utest syntax. Also not supported in Scala 3.
* Move objects used in tests to be stable and not defined in the utest macro. Without this change the Scala 3 version doesn't compile.

## Commits

* Update build system for Scala 3

* Initial Scala 3 (dotty) port

* Only use str-to-str concatenation

There is a bug in the dotty compiler? scala/scala3#13518

scalatags.js[3.0.1,1.7.0].compile java.lang.AssertionError: assertion failed
    scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:11)
    dotty.tools.backend.sjs.JSCodeGen.genStringConcat(JSCodeGen.scala:2487)
    dotty.tools.backend.sjs.JSCodeGen.genPrimitiveOp(JSCodeGen.scala:2098)

* Bump to Scala 3.0.0

* wip

* Use string interpolation instead of `+`

* Gitignore /.bsp from Mill BSP

* Remove space in quoted start

* Reduce duplicated code and fix some compilation error

* Remove some lazy vals and revert renames

* Most code compiles

* All code compiling now

* Fix macro to use declaredFields

* Remove pprint

* Remove empty companion objects

* Remove old comment

* Avoid to define lazy val Frags

* Revert some changes not necessary for Scala 3

* Revert formatting change

* Remove unused import

* Revert spurious change

* Remove spurious import

* Refactor filter for ScalaJS versions

Co-authored-by: Sakib Hadžiavdić <sake92@users.noreply.github.com>

Co-authored-by: Edward Wang <edward.c.wang@compdigitec.com>
Co-authored-by: Sakib Hadžiavdić <sake92@users.noreply.github.com>
olsdavis pushed a commit to olsdavis/dotty that referenced this issue Apr 4, 2022
…a TermRef.

Sometimes, the argument string's `tpe` can be a `TermRef`, in which
case it is not directly a ref to `StringClass`. That was triggering
the assertion.

The assertions and the calls to `makePrimitiveBox` have actually
not been needed for a long time. The IR supports the arguments to a
`String_+` operator to be of any type. So we fix the issue by
removing all of that and directly emitting the `String_+`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants