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

Runtime error when a single '%' character is specified for a string literal with f interpolator #11256

Closed
kynthus opened this issue Jan 30, 2021 · 3 comments · Fixed by #13367
Milestone

Comments

@kynthus
Copy link

kynthus commented Jan 30, 2021

Compiler version

3.0.0-M3

Minimized code

val x: Int = 5
val y: Int = 2

println(f"x % y = ${x % y}%d") // java.util.UnknownFormatConversionException

Output

Starting scala3 REPL...
Scala compiler version 3.0.0-M3 -- Copyright 2002-2020, LAMP/EPFL
scala> val x: Int = 5
     | val y: Int = 2
     |
     | println(f"x % y = ${x % y}%d")
java.util.UnknownFormatConversionException: Conversion = 'y'
  at java.util.Formatter$FormatSpecifier.conversion(Unknown Source)
  at java.util.Formatter$FormatSpecifier.<init>(Unknown Source)
  at java.util.Formatter.parse(Unknown Source)
  at java.util.Formatter.format(Unknown Source)
  at java.util.Formatter.format(Unknown Source)
  at java.lang.String.format(Unknown Source)
  at scala.collection.StringOps$.format$extension(StringOps.scala:968)
  ... 27 elided
java.lang.NoClassDefFoundError: Could not initialize class rs$line$1$
  at rs$line$1.y(rs$line$1)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  at java.lang.reflect.Method.invoke(Unknown Source)
  at dotty.tools.repl.Rendering.$anonfun$3(Rendering.scala:84)
  at scala.Option.map(Option.scala:242)
  at dotty.tools.repl.Rendering.valueOf(Rendering.scala:84)
  at dotty.tools.repl.Rendering.renderVal(Rendering.scala:121)
  at dotty.tools.repl.ReplDriver.$anonfun$13(ReplDriver.scala:308)
  at scala.collection.immutable.List.flatMap(List.scala:293)
  at scala.collection.immutable.List.flatMap(List.scala:79)
  at dotty.tools.repl.ReplDriver.extractAndFormatMembers$2(ReplDriver.scala:308)
  at dotty.tools.repl.ReplDriver.renderDefinitions$$anonfun$2(ReplDriver.scala:331)
  at scala.Option.map(Option.scala:242)
  at dotty.tools.repl.ReplDriver.renderDefinitions(ReplDriver.scala:334)
  at dotty.tools.repl.ReplDriver.compile$$anonfun$2(ReplDriver.scala:253)
  at scala.util.Either.fold(Either.scala:189)
  at dotty.tools.repl.ReplDriver.compile(ReplDriver.scala:269)
  at dotty.tools.repl.ReplDriver.interpret(ReplDriver.scala:197)
  at dotty.tools.repl.ReplDriver.loop$1(ReplDriver.scala:130)
  at dotty.tools.repl.ReplDriver.runUntilQuit$$anonfun$1(ReplDriver.scala:133)
  at dotty.tools.repl.ReplDriver.withRedirectedOutput(ReplDriver.scala:152)
  at dotty.tools.repl.ReplDriver.runUntilQuit(ReplDriver.scala:133)
  at dotty.tools.repl.Main$.main(Main.scala:6)
  at dotty.tools.repl.Main.main(Main.scala)
java.lang.NoClassDefFoundError: Could not initialize class rs$line$1$
  at rs$line$1.res0(rs$line$1)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  at java.lang.reflect.Method.invoke(Unknown Source)
  at dotty.tools.repl.Rendering.$anonfun$3(Rendering.scala:84)
  at scala.Option.map(Option.scala:242)
  at dotty.tools.repl.Rendering.valueOf(Rendering.scala:84)
  at dotty.tools.repl.Rendering.renderVal(Rendering.scala:121)
  at dotty.tools.repl.ReplDriver.$anonfun$13(ReplDriver.scala:308)
  at scala.collection.immutable.List.flatMap(List.scala:293)
  at scala.collection.immutable.List.flatMap(List.scala:79)
  at dotty.tools.repl.ReplDriver.extractAndFormatMembers$2(ReplDriver.scala:308)
  at dotty.tools.repl.ReplDriver.renderDefinitions$$anonfun$2(ReplDriver.scala:331)
  at scala.Option.map(Option.scala:242)
  at dotty.tools.repl.ReplDriver.renderDefinitions(ReplDriver.scala:334)
  at dotty.tools.repl.ReplDriver.compile$$anonfun$2(ReplDriver.scala:253)
  at scala.util.Either.fold(Either.scala:189)
  at dotty.tools.repl.ReplDriver.compile(ReplDriver.scala:269)
  at dotty.tools.repl.ReplDriver.interpret(ReplDriver.scala:197)
  at dotty.tools.repl.ReplDriver.loop$1(ReplDriver.scala:130)
  at dotty.tools.repl.ReplDriver.runUntilQuit$$anonfun$1(ReplDriver.scala:133)
  at dotty.tools.repl.ReplDriver.withRedirectedOutput(ReplDriver.scala:152)
  at dotty.tools.repl.ReplDriver.runUntilQuit(ReplDriver.scala:133)
  at dotty.tools.repl.Main$.main(Main.scala:6)
  at dotty.tools.repl.Main.main(Main.scala)

Expectation

On Scala 2.10.2 to the current stable version,
I get a compile error when specifying a single '%' character.

Welcome to Scala version 2.10.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val x: Int = 5
x: Int = 5

scala> val y: Int = 2
y: Int = 2

scala>

scala> println(f"x % y = ${x % y}%d")
<console>:10: error: percent signs not directly following splicees must be escaped
              println(f"x % y = ${x % y}%d")
                          ^
Welcome to Scala 2.13.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_202).
Type in expressions for evaluation. Or try :help.

scala> val x: Int = 5
     | val y: Int = 2
     |
     | println(f"x % y = ${x % y}%d")
       println(f"x % y = ${x % y}%d")
                     ^
On line 4: error: illegal conversion character 'y'

So I expected it to be the same in Scala 3.

@som-snytt
Copy link
Contributor

Added to #9939

@kynthus
Copy link
Author

kynthus commented Jan 30, 2021

@som-snytt Thanks for the addition as a related issue!

@som-snytt
Copy link
Contributor

Worth noting "% y" looks like a format conversion because space char is a legal flag ("leading space for positive values").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants