Closed scabug closed 5 years ago
Imported From: https://issues.scala-lang.org/browse/SI-9532?orig=1 Reporter: @som-snytt Affected Versions: 2.11.7
@retronym said (edited on Oct 24, 2015 12:14:58 PM UTC): I think the principled solution here is for constant folding to operate on types only and leave terms alone. This is actually on our wishlist for 2.12, but an area where help would be much appreciated!
The idea is to take the best of both worlds terms are left as written, but the types are constant folded.
So 1 + 1
would give (1 + 1): 2.type
. Right now, the regular compiler gives: 2 : 2.type
, and Scaladoc / pressy gives: 1 + 1: Int
.
Here's my moth-balled attempt at this: https://github.com/scala/scala/compare/2.11.x...retronym:topic/const-type-fold
The problem will be to adapt later compiler phases that match on Literal(Constant(...))
to instead check whether the tree has a constant type. This of course gets slightly harder when the code you need to update is in other projects like scala-{ide,refactoring}.
A stepping stone solution would be just to use this new approach for scaladoc, and keep it off by default for other compilation modes. We could then get downstream code changed, before enabling this by default or (by edict).
See https://groups.google.com/forum/#!topic/scala-internals/b95Y-GbXVGA for another beneficiary of such a move, the incremental compiler.
@adriaanm said: And here's my attempt: https://github.com/adriaanm/scala/tree/constantfold-in-type...
Before and after:
$ ~/scala-2.12.6/bin/scaladoc -d /tmp t9532.scala
t9532.scala:4: warning: Implementation restriction: subclassing Classfile does not
make your annotation visible at runtime. If that is what
you want, you must write the annotation class in Java.
class MyAnnotation(val s: String) extends ClassfileAnnotation
^
t9532.scala:9: error: annotation argument needs to be a constant; found: T.this.K
@MyAnnotation(s = K) // not a constant under scaladoc
^
model contains 4 documentable templates
one warning found
one error found
$ ~/scala-2.13.0-M5/bin/scaladoc -d /tmp t9532.scala
model contains 4 documentable templates
Scaladoc still sees original trees, albeit with folded constant types. Macros that require literal trees will be disappointed. For example,
M.lit(StringContext("hello, " + who).f())
results in
$ ~/scala-2.13.0-M5/bin/scaladoc -d /tmp litcheck.scala
litcheck.scala:13: error: exception during macro expansion:
java.lang.IllegalArgumentException: internal error: argument parts must be a list of string literals
at scala.tools.reflect.FormatInterpolator.copyPart$1(FormatInterpolator.scala:81)
at scala.tools.reflect.FormatInterpolator.$anonfun$interpolated$3(FormatInterpolator.scala:175)
at scala.tools.reflect.FormatInterpolator.interpolated(FormatInterpolator.scala:174)
at scala.tools.reflect.FormatInterpolator.interpolate(FormatInterpolator.scala:37)
M.lit(StringContext("hello, " + who).f())
^
model contains 4 documentable templates
Scaladoc turns off constant folding, but that affects whether annotations requiring constant expressions can be compiled.
As asked on stack overflow.