Description
I just remembered, there is a follow-up optimization related to this, range literals can be embedded in the AST:
$ ruby -ve '2.times { p (1..2).object_id }'
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
60
60
However this is a problem for AST sharing (sharing the same AST for multiple execution contexts, which have different Ruby classes, etc), because RubyRange objects are currently not context-independent, they point to a given RubyClass (private RubyClass metaClass;
in RubyDynamicObject
).
So to solve this we would need RubyIntRange/RubyLongRange to no longer inherit from RubyRange (we'd also just remove RubyRange), and instead inherit from ImmutableRubyObject
.
Then in the translator when building a literal Range with int or long literals for both begin & end (non-beginless & non-endless) we could create a RubyIntRange/RubyLongRange directly in the translator (in org.truffleruby.parser.BodyTranslator#visitDotNode
) and use an ObjectLiteralNode to embed the range instance in the AST.
For the cases we need to create a non-frozen range with int/long begin/end we'd go to RubyObjectRange then (e.g., for Range#dup
).
Originally posted by @eregon in #2570 (comment)
cc @MattAlp