SI-8650 F-interpolator inlines literals#4316
Conversation
FormatInterpolator checks that indexed specifiers (like %3$d) refer to
arguments that are compatible with the specifier.
When arguments are literal constants, aka constant value expressions,
they are inlined using the specifier.
Other checks are added or improved, including a check for duplicate
flags.
Sample debug output showing that only one arg is evaluated at runtime:
```
scala> :load -v test.script
Loading test.script...
scala> def x = System.currentTimeMillis ; final val i = 17 ; final val pi = 3.14 ; final val s = "hello, world"
x: Long
i: Int(17) = 17
pi: Double(3.14) = 3.14
s: String("hello, world") = hello, world
scala> f"$x $pi%f %<s $i%d $s %1$$d"
Format '%s 3.140000 3.14 17 hello, world %1$d' with 1 tmps and 1 args
res0: String = 1422731811259 3.140000 3.14 17 hello, world 1422731811259
```
It doesn't attempt (bother) to inline enum symbols and class constants.
The "incompatible arg" error caret position could be improved.
For inlining purposes, use ConstantFolder and constant.convertTo to handle expressions and conversions.
The string conversion only requires a top type, but preserve the actual type so that indexed references work. As an edge case, args typed `Any` are downcast to `AnyRef` for the call to `String.format`.
One might hope that \a\v\e means something besides aloha. This commit adds a suggestion for the ASCII control codes.
|
Since the 2.11.6 deadline is extremely nigh, I've tentatively postponed this PR (along with other recent ones) to 2.11.7. I'll make a pass through reviewed 2.11.7 PRs on Friday and move them back to 2.11.6 where feasible. In the mean time, feel free to let me know if you'd like some help getting this reviewed by then. |
|
@som-snytt Would it make sense to macroify the s-interpolator, too? (Btw, any plans for regextractor?) |
87a0adb to
f38f483
Compare
f38f483 to
fbd01b6
Compare
/rebuild |
This error has been haunting us recently, firstly on Greg's machine when compiling the compiler using the new SBT build, and more recently during PR validation in scala#4316. This commit will output an error like: symbol value c#16812 does not exist in Macro.impl, which contains locals value a#16810, value b#16811 I've included symbol IDs in the hope that they will prove useful. It seems that synthetic identifiers generated by the pattern matcher are often seen in the vicinity of this bug.
|
I've added a better diagnostic for that compiler crash in #4397. I can't see how it is related to this change. /rebuild |
|
@retronym I did a quick rebase earlier today, something might have got munged... |
fbd01b6 to
87a0adb
Compare
|
FYI, I reverted this to the unrebased, and I'm trying out a fresh rebase on the other PR. It was nice getting the green checks here for free. Jenkins has elephantine memory. Pachydermal recall. |
|
/rebuild for the less green ones. |
FormatInterpolator emits a call to
String.format(s, args...)and inlinesconstant expressions in the string.
Indexed args are verified for correctness.