Closed DmytroMitin closed 1 year ago
The example in the reflection scaladoc covers special handling of constants classOf[T]
and Java enum
.
But they are naively unwrapped at eval
.
The comment:
People are very frequently using c.eval in order to obtain underlying values of literals. Spinning up a new compiler for that modest purpose is a gross waste of fossil fuels.
@som-snytt Many thanks. So evaluating a tree of Class[_]
(enum value) into Type
(Symbol
) was intended behavior. I don't know whether the behavior should change. With new implementation this stops to work for classes not existing yet during macro expansion (although previous implementation was slightly inconsistent for classOf[String]
/ Class.forName("java.lang.String")
).
My point was that it's weird that the behavior depends on whether we define a local variable inside a macro.
Reproduction steps
Scala version: 2.13.10
classValue
in a macro then upon expansion the macro producesClassCastException
https://scastie.scala-lang.org/DmytroMitin/RINjJfNsRNqprn9nR1ZpDQ/9 (toolbox is not used for actual reproduction, it's just for Scastie because it doesn't support multiple files/subprojects).
https://scastie.scala-lang.org/DmytroMitin/RINjJfNsRNqprn9nR1ZpDQ/18
Problem
The macro should expand successfully both times and
c.eval
should produceClass[_]
both times.A workaround is casting (when possible)
https://scastie.scala-lang.org/DmytroMitin/RINjJfNsRNqprn9nR1ZpDQ/33
or runtime reflection in macros
https://scastie.scala-lang.org/DmytroMitin/RINjJfNsRNqprn9nR1ZpDQ/32
If we remove
c.untypecheck
or replace it withc.resetAllAttrs
(from https://github.com/scalamacros/resetallattrs) nothing changes.If we replace existential with
Class[T]
nothing changes.Discovered here: https://stackoverflow.com/questions/71390113/get-annotations-from-class-in-scala-3-macros