Open mkeskells opened 6 years ago
(PRIVATE: Long) << AntiShift
is not a constant expression, so it fall through the constant folder.
We could update that to make a widening of a constant also be a constant. In addition to changing that code, this part of the spec would need to be augmented.
Or, without changing the spec, we could just use 0L + PRIVATE
instead of (PRIVATE: Long)
.
scala> object C { final val PRIVATE = 1 << 2; final val AntiShift = 56; final val notPRIVATE = (0L + PRIVATE) << AntiShift }
defined object C
scala> class Test { def foo = C.notPRIVATE }
defined class Test
scala> :javap -c Test#foo
public long foo();
Code:
0: ldc2_w #16 // long 288230376151711744l
3: lreturn
I think that it is worth considering changing the spec, as that will be beneficial to other cases outside the Flags.
It seem strange that implicit widening is optimised, but explicit is not. Presumably narrowing isn't either
This will have an impact on performance I think as these constants get inlined to the caller @retronym @adriaanm do you have any concerns about widened the spec (in 2.13)
discussed with @retronym on gitter - ~Long is not folding as expected
WIP https://github.com/scala/scala/compare/2.13.x...retronym:topic/constant-folder-unary?expand=1
There is overlap with https://github.com/scala/scala/pull/6452, which also needs to introduce some constant-related logic in typedSelect
. We're discussing it all over there.
It seems that some constants are deferred to run time. This means that they generate more bytecode, and cant (probably) be inlined
e.g. Flags.scala has code like
generate bytecode like
but not for all fields e.g