scala / bug

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

String interpolation fails to compile running on JDK 20 when using release:11 compiler option #12761

Closed arixmkii closed 1 year ago

arixmkii commented 1 year ago

Reproduction steps

Scala version: 2.13.10

object A {
  def a(s: String): String = s"S: $s"
}

Problem

When trying to compile on JDK 20:

% java -version             
openjdk version "20" 2023-03-21
OpenJDK Runtime Environment Temurin-20+36 (build 20+36)
OpenJDK 64-Bit Server VM Temurin-20+36 (build 20+36, mixed mode)

% scala -version
Scala code runner version 2.13.10 -- Copyright 2002-2022, LAMP/EPFL and Lightbend, Inc.

% scalac -release:11 A.scala
error: Error while emitting A$
Unsupported class file major version 64
1 error

Compiles just fine with Temuring 17 JDK.

Platforms tested on:

som-snytt commented 1 year ago

And I just joked that "adding strings" was the only API I never need to consult the docs about.

som-snytt commented 1 year ago

https://github.com/scala/scala/pull/10184 is the version bump

but why is it reading class files under --release?

at scala.tools.nsc.backend.jvm.opt.ByteCodeRepository.parseClass(ByteCodeRepository.scala:295)

at scala.tools.nsc.backend.jvm.analysis.BackendUtils.collectNestedClasses(BackendUtils.scala:422)
at scala.tools.nsc.backend.jvm.PostProcessor.setInnerClasses(PostProcessor.scala:136)

PARSE CLASS(java.lang.invoke.MethodHandles$Lookup)  // bit of debug
PARSE CLASS(java.lang.invoke.MethodHandles)

The successful compile outputs

1: invokedynamic #27,  0             // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;

InnerClasses:
  public static final #13= #10 of #12;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles

This might have been a use case for --release:11 --target:8 except that does not work around it.

          // `StringConcatFactory` only got added in JDK 9, so use `StringBuilder` for lower
          if (classfileVersion.get < asm.Opcodes.V9) {

because brilliantly

def targetValue: String = releaseValue.getOrElse(target.value)
SethTisue commented 1 year ago

nice catch, and good timing!