Skip to content

Commit 2f78a96

Browse files
moste00eregon
authored andcommitted
cleaner way to make compact hashes the default
1 parent a116b22 commit 2f78a96

File tree

12 files changed

+74
-65
lines changed

12 files changed

+74
-65
lines changed

src/main/java/org/truffleruby/core/hash/HashLiteralNode.java

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
*/
1010
package org.truffleruby.core.hash;
1111

12+
import org.truffleruby.RubyLanguage;
1213
import org.truffleruby.core.hash.library.BucketsHashStore;
1314
import org.truffleruby.core.hash.library.CompactHashStore;
1415
import org.truffleruby.core.hash.library.EmptyHashStore;
1516
import org.truffleruby.core.hash.library.PackedHashStoreLibrary;
1617
import org.truffleruby.core.hash.library.PackedHashStoreLibraryFactory;
17-
import org.truffleruby.language.RubyBaseNode;
1818
import org.truffleruby.language.RubyContextSourceNode;
1919
import org.truffleruby.language.RubyNode;
2020

@@ -30,24 +30,14 @@ protected HashLiteralNode(RubyNode[] keyValues) {
3030
this.keyValues = keyValues;
3131
}
3232

33-
public static final class BigHashConfiguredStrategy extends RubyBaseNode {
34-
private BigHashConfiguredStrategy() {
35-
isBuckets = getContext().getOptions().BIG_HASH_STRATEGY;
36-
}
37-
38-
// dummy instance, so we can call getContext instance method, never used
39-
private static final BigHashConfiguredStrategy bh = new BigHashConfiguredStrategy();
40-
public static boolean isBuckets;
41-
}
42-
43-
public static HashLiteralNode create(RubyNode[] keyValues) {
33+
public static HashLiteralNode create(RubyNode[] keyValues, RubyLanguage rubyLanguage) {
4434
if (keyValues.length == 0) {
4535
return new EmptyHashStore.EmptyHashLiteralNode();
4636
} else if (keyValues.length <= PackedHashStoreLibrary.MAX_ENTRIES * 2) {
4737
return PackedHashStoreLibraryFactory.SmallHashLiteralNodeGen.create(keyValues);
4838
} else {
49-
return BigHashConfiguredStrategy.isBuckets
50-
? new BucketsHashStore.GenericHashLiteralNode(keyValues)
39+
return rubyLanguage.options.BIG_HASH_STRATEGY_IS_BUCKETS
40+
? new BucketsHashStore.BucketHashLiteralNode(keyValues)
5141
: new CompactHashStore.CompactHashLiteralNode(keyValues);
5242
}
5343
}

src/main/java/org/truffleruby/core/hash/library/BucketsHashStore.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,12 +571,12 @@ HashLookupResult lookup(RubyHash hash, Entry[] entries, Object key,
571571

572572
}
573573

574-
public static final class GenericHashLiteralNode extends HashLiteralNode {
574+
public static final class BucketHashLiteralNode extends HashLiteralNode {
575575

576576
@Child HashStoreLibrary hashes;
577577
private final int bucketsCount;
578578

579-
public GenericHashLiteralNode(RubyNode[] keyValues) {
579+
public BucketHashLiteralNode(RubyNode[] keyValues) {
580580
super(keyValues);
581581
bucketsCount = growthCapacityGreaterThan(keyValues.length / 2);
582582
}
@@ -608,7 +608,7 @@ public Object execute(VirtualFrame frame) {
608608

609609
@Override
610610
public RubyNode cloneUninitialized() {
611-
var copy = new GenericHashLiteralNode(cloneUninitialized(keyValues));
611+
var copy = new BucketHashLiteralNode(cloneUninitialized(keyValues));
612612
return copy.copyFlags(this);
613613
}
614614

src/main/java/org/truffleruby/core/hash/library/CompactHashStore.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ private CompactHashStore(int[] index, Object[] kvs, int kvStoreInsertionPos, int
134134
}
135135

136136
public CompactHashStore(int capacity) {
137-
if (capacity < 1 || capacity > (1 << 28)) {
137+
if (capacity < 1 || capacity >= (1 << 28)) {
138138
throw shouldNotReachHere();
139139
}
140140

@@ -152,7 +152,7 @@ public CompactHashStore(int capacity) {
152152
}
153153

154154
private static int roundUpwardsToNearestPowerOf2(int num) {
155-
return Integer.highestOneBit(num - 1) << 1;
155+
return Integer.highestOneBit(num) << 1; // rounds powers of 2 themselves : 1 => 2, 2 => 4, 3 => 4, 4 => 8, ...
156156
}
157157

158158
public void putHashKeyValue(int hashcode, Object key, Object value) {

src/main/java/org/truffleruby/core/hash/library/PackedHashStoreLibrary.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.oracle.truffle.api.dsl.Cached;
4040
import com.oracle.truffle.api.dsl.Cached.Exclusive;
4141
import com.oracle.truffle.api.dsl.Cached.Shared;
42+
import com.oracle.truffle.api.dsl.GenerateInline;
4243
import com.oracle.truffle.api.dsl.GenerateUncached;
4344
import com.oracle.truffle.api.dsl.ImportStatic;
4445
import com.oracle.truffle.api.dsl.Specialization;
@@ -208,6 +209,7 @@ static boolean set(Object[] store, RubyHash hash, Object key, Object value, bool
208209
@Cached @Shared CompareHashKeysNode compareHashKeys,
209210
@CachedLibrary(limit = "hashStrategyLimit()") HashStoreLibrary hashes,
210211
@Cached InlinedConditionProfile withinCapacity,
212+
@Cached(inline = true) PromoteToBigHashNode promoteToBigHash,
211213
@Bind("this") Node node) {
212214

213215
assert verify(store, hash);
@@ -235,19 +237,13 @@ static boolean set(Object[] store, RubyHash hash, Object key, Object value, bool
235237
return true;
236238
}
237239

238-
promoteToBigHash(store, hash, size);
240+
241+
assert size == MAX_ENTRIES;
242+
promoteToBigHash.execute(node, store, hash, MAX_ENTRIES);
239243

240244
hashes.set(hash.store, hash, key2, value, byIdentity);
241245
return true;
242246
}
243-
244-
private static void promoteToBigHash(Object[] store, RubyHash hash, int size) {
245-
if (HashLiteralNode.BigHashConfiguredStrategy.isBuckets) {
246-
promoteToBuckets(hash, store, size);
247-
} else {
248-
promoteToCompact(hash, store, size);
249-
}
250-
}
251247
}
252248

253249
@ExportMessage
@@ -416,6 +412,21 @@ static boolean verify(Object[] store, RubyHash hash) {
416412
// endregion
417413
// region Nodes
418414

415+
@GenerateUncached
416+
@GenerateInline
417+
abstract static class PromoteToBigHashNode extends RubyBaseNode {
418+
public abstract void execute(Node node, Object[] store, RubyHash hash, int size);
419+
420+
@Specialization
421+
void promoteToBigHash(Object[] store, RubyHash hash, int size) {
422+
if (getLanguage().options.BIG_HASH_STRATEGY_IS_BUCKETS) {
423+
promoteToBuckets(hash, store, size);
424+
} else {
425+
promoteToCompact(hash, store, size);
426+
}
427+
}
428+
}
429+
419430
@GenerateUncached
420431
@ImportStatic(HashGuards.class)
421432
public abstract static class LookupPackedEntryNode extends RubyBaseNode {

src/main/java/org/truffleruby/options/LanguageOptions.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public final class LanguageOptions {
4343
public final boolean LAZY_TRANSLATION_USER;
4444
/** --backtraces-omit-unused=true */
4545
public final boolean BACKTRACES_OMIT_UNUSED;
46+
/** --buckets-big-hash=false */
47+
public final boolean BIG_HASH_STRATEGY_IS_BUCKETS;
4648
/** --lazy-translation-log=false */
4749
public final boolean LAZY_TRANSLATION_LOG;
4850
/** --constant-dynamic-lookup-log=false */
@@ -141,6 +143,7 @@ public LanguageOptions(Env env, OptionValues options, boolean singleContext) {
141143
STDLIB_AS_INTERNAL = options.get(OptionsCatalog.STDLIB_AS_INTERNAL_KEY);
142144
LAZY_TRANSLATION_USER = options.hasBeenSet(OptionsCatalog.LAZY_TRANSLATION_USER_KEY) ? options.get(OptionsCatalog.LAZY_TRANSLATION_USER_KEY) : LAZY_CALLTARGETS;
143145
BACKTRACES_OMIT_UNUSED = options.get(OptionsCatalog.BACKTRACES_OMIT_UNUSED_KEY);
146+
BIG_HASH_STRATEGY_IS_BUCKETS = options.get(OptionsCatalog.BIG_HASH_STRATEGY_IS_BUCKETS_KEY);
144147
LAZY_TRANSLATION_LOG = options.get(OptionsCatalog.LAZY_TRANSLATION_LOG_KEY);
145148
LOG_DYNAMIC_CONSTANT_LOOKUP = options.get(OptionsCatalog.LOG_DYNAMIC_CONSTANT_LOOKUP_KEY);
146149
LAZY_BUILTINS = options.hasBeenSet(OptionsCatalog.LAZY_BUILTINS_KEY) ? options.get(OptionsCatalog.LAZY_BUILTINS_KEY) : LAZY_CALLTARGETS;
@@ -208,6 +211,8 @@ public Object fromDescriptor(OptionDescriptor descriptor) {
208211
return LAZY_TRANSLATION_USER;
209212
case "ruby.backtraces-omit-unused":
210213
return BACKTRACES_OMIT_UNUSED;
214+
case "ruby.buckets-big-hash":
215+
return BIG_HASH_STRATEGY_IS_BUCKETS;
211216
case "ruby.lazy-translation-log":
212217
return LAZY_TRANSLATION_LOG;
213218
case "ruby.constant-dynamic-lookup-log":
@@ -310,6 +315,7 @@ public static boolean areOptionsCompatible(OptionValues one, OptionValues two) {
310315
one.get(OptionsCatalog.STDLIB_AS_INTERNAL_KEY).equals(two.get(OptionsCatalog.STDLIB_AS_INTERNAL_KEY)) &&
311316
one.get(OptionsCatalog.LAZY_TRANSLATION_USER_KEY).equals(two.get(OptionsCatalog.LAZY_TRANSLATION_USER_KEY)) &&
312317
one.get(OptionsCatalog.BACKTRACES_OMIT_UNUSED_KEY).equals(two.get(OptionsCatalog.BACKTRACES_OMIT_UNUSED_KEY)) &&
318+
one.get(OptionsCatalog.BIG_HASH_STRATEGY_IS_BUCKETS_KEY).equals(two.get(OptionsCatalog.BIG_HASH_STRATEGY_IS_BUCKETS_KEY)) &&
313319
one.get(OptionsCatalog.LAZY_TRANSLATION_LOG_KEY).equals(two.get(OptionsCatalog.LAZY_TRANSLATION_LOG_KEY)) &&
314320
one.get(OptionsCatalog.LOG_DYNAMIC_CONSTANT_LOOKUP_KEY).equals(two.get(OptionsCatalog.LOG_DYNAMIC_CONSTANT_LOOKUP_KEY)) &&
315321
one.get(OptionsCatalog.LAZY_BUILTINS_KEY).equals(two.get(OptionsCatalog.LAZY_BUILTINS_KEY)) &&
@@ -429,6 +435,13 @@ public static boolean areOptionsCompatibleOrLog(TruffleLogger logger, LanguageOp
429435
return false;
430436
}
431437

438+
oldValue = oldOptions.BIG_HASH_STRATEGY_IS_BUCKETS;
439+
newValue = newOptions.BIG_HASH_STRATEGY_IS_BUCKETS;
440+
if (!newValue.equals(oldValue)) {
441+
logger.fine("not reusing pre-initialized context: --buckets-big-hash differs, was: " + oldValue + " and is now: " + newValue);
442+
return false;
443+
}
444+
432445
oldValue = oldOptions.LAZY_TRANSLATION_LOG;
433446
newValue = newOptions.LAZY_TRANSLATION_LOG;
434447
if (!newValue.equals(oldValue)) {

src/main/java/org/truffleruby/options/Options.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,6 @@ public final class Options {
9393
public final boolean EXCEPTIONS_WARN_OUT_OF_MEMORY;
9494
/** --backtraces-interleave-java=false */
9595
public final boolean BACKTRACES_INTERLEAVE_JAVA;
96-
/** --buckets-big-hash=false */
97-
public final boolean BIG_HASH_STRATEGY;
9896
/** --backtraces-on-interrupt=false */
9997
public final boolean BACKTRACE_ON_INTERRUPT;
10098
/** --backtraces-sigalrm=!EMBEDDED */
@@ -249,7 +247,6 @@ public Options(Env env, OptionValues options, LanguageOptions languageOptions) {
249247
EXCEPTIONS_WARN_STACKOVERFLOW = options.get(OptionsCatalog.EXCEPTIONS_WARN_STACKOVERFLOW_KEY);
250248
EXCEPTIONS_WARN_OUT_OF_MEMORY = options.get(OptionsCatalog.EXCEPTIONS_WARN_OUT_OF_MEMORY_KEY);
251249
BACKTRACES_INTERLEAVE_JAVA = options.get(OptionsCatalog.BACKTRACES_INTERLEAVE_JAVA_KEY);
252-
BIG_HASH_STRATEGY = options.get(OptionsCatalog.BIG_HASH_STRATEGY_KEY);
253250
BACKTRACE_ON_INTERRUPT = options.get(OptionsCatalog.BACKTRACE_ON_INTERRUPT_KEY);
254251
BACKTRACE_ON_SIGALRM = options.hasBeenSet(OptionsCatalog.BACKTRACE_ON_SIGALRM_KEY) ? options.get(OptionsCatalog.BACKTRACE_ON_SIGALRM_KEY) : !EMBEDDED;
255252
BACKTRACE_ON_RAISE = options.get(OptionsCatalog.BACKTRACE_ON_RAISE_KEY);
@@ -381,8 +378,6 @@ public Object fromDescriptor(OptionDescriptor descriptor) {
381378
return EXCEPTIONS_WARN_OUT_OF_MEMORY;
382379
case "ruby.backtraces-interleave-java":
383380
return BACKTRACES_INTERLEAVE_JAVA;
384-
case "ruby.buckets-big-hash":
385-
return BIG_HASH_STRATEGY;
386381
case "ruby.backtraces-on-interrupt":
387382
return BACKTRACE_ON_INTERRUPT;
388383
case "ruby.backtraces-sigalrm":

src/main/java/org/truffleruby/parser/BodyTranslator.java

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,22 @@
99
*/
1010
package org.truffleruby.parser;
1111

12-
import com.oracle.truffle.api.strings.InternalByteArray;
13-
import com.oracle.truffle.api.strings.TruffleString;
12+
import java.math.BigInteger;
13+
import java.nio.charset.StandardCharsets;
14+
import java.util.ArrayDeque;
15+
import java.util.ArrayList;
16+
import java.util.Arrays;
17+
import java.util.Deque;
18+
import java.util.Iterator;
19+
import java.util.List;
1420

1521
import org.jcodings.Encoding;
1622
import org.joni.NameEntry;
1723
import org.joni.Regex;
1824
import org.joni.Syntax;
1925
import org.truffleruby.RubyContext;
2026
import org.truffleruby.RubyLanguage;
27+
import org.truffleruby.annotations.Split;
2128
import org.truffleruby.builtins.PrimitiveNodeConstructor;
2229
import org.truffleruby.core.CoreLibrary;
2330
import org.truffleruby.core.IsNilNode;
@@ -49,12 +56,12 @@
4956
import org.truffleruby.core.regexp.RegexWarnDeferredCallback;
5057
import org.truffleruby.core.regexp.RegexpOptions;
5158
import org.truffleruby.core.regexp.RubyRegexp;
52-
import org.truffleruby.core.string.TStringWithEncoding;
5359
import org.truffleruby.core.string.FrozenStrings;
60+
import org.truffleruby.core.string.ImmutableRubyString;
5461
import org.truffleruby.core.string.InterpolatedStringNode;
55-
import org.truffleruby.core.string.TStringConstants;
5662
import org.truffleruby.core.string.StringUtils;
57-
import org.truffleruby.core.string.ImmutableRubyString;
63+
import org.truffleruby.core.string.TStringConstants;
64+
import org.truffleruby.core.string.TStringWithEncoding;
5865
import org.truffleruby.language.LexicalScope;
5966
import org.truffleruby.language.Nil;
6067
import org.truffleruby.language.NotProvided;
@@ -96,10 +103,10 @@
96103
import org.truffleruby.language.defined.DefinedWrapperNode;
97104
import org.truffleruby.language.dispatch.RubyCallNodeParameters;
98105
import org.truffleruby.language.exceptions.EnsureNodeGen;
99-
import org.truffleruby.language.exceptions.RescueStandardErrorNode;
100106
import org.truffleruby.language.exceptions.RescueClassesNode;
101107
import org.truffleruby.language.exceptions.RescueNode;
102108
import org.truffleruby.language.exceptions.RescueSplatNode;
109+
import org.truffleruby.language.exceptions.RescueStandardErrorNode;
103110
import org.truffleruby.language.exceptions.TryNodeGen;
104111
import org.truffleruby.language.globals.AliasGlobalVarNode;
105112
import org.truffleruby.language.globals.ReadGlobalVariableNodeGen;
@@ -127,21 +134,20 @@
127134
import org.truffleruby.language.methods.LiteralMethodDefinitionNode;
128135
import org.truffleruby.language.methods.ModuleBodyDefinition;
129136
import org.truffleruby.language.methods.SharedMethodInfo;
130-
import org.truffleruby.annotations.Split;
131137
import org.truffleruby.language.objects.DefineClassNode;
132138
import org.truffleruby.language.objects.DefineModuleNode;
133139
import org.truffleruby.language.objects.DefineModuleNodeGen;
134140
import org.truffleruby.language.objects.DynamicLexicalScopeNode;
135141
import org.truffleruby.language.objects.GetDynamicLexicalScopeNode;
136142
import org.truffleruby.language.objects.InsideModuleDefinitionNode;
137143
import org.truffleruby.language.objects.LexicalScopeNode;
138-
import org.truffleruby.language.objects.WriteInstanceVariableNodeGen;
139-
import org.truffleruby.language.objects.classvariables.ReadClassVariableNode;
140144
import org.truffleruby.language.objects.ReadInstanceVariableNode;
141145
import org.truffleruby.language.objects.RunModuleDefinitionNode;
142146
import org.truffleruby.language.objects.SelfNode;
143147
import org.truffleruby.language.objects.SingletonClassNode.SingletonClassASTNode;
144148
import org.truffleruby.language.objects.SingletonClassNodeGen.SingletonClassASTNodeGen;
149+
import org.truffleruby.language.objects.WriteInstanceVariableNodeGen;
150+
import org.truffleruby.language.objects.classvariables.ReadClassVariableNode;
145151
import org.truffleruby.language.objects.classvariables.WriteClassVariableNode;
146152
import org.truffleruby.language.yield.YieldExpressionNode;
147153
import org.truffleruby.parser.ast.AliasParseNode;
@@ -261,15 +267,8 @@
261267
import com.oracle.truffle.api.nodes.NodeUtil;
262268
import com.oracle.truffle.api.source.Source;
263269
import com.oracle.truffle.api.source.SourceSection;
264-
265-
import java.math.BigInteger;
266-
import java.nio.charset.StandardCharsets;
267-
import java.util.ArrayDeque;
268-
import java.util.ArrayList;
269-
import java.util.Arrays;
270-
import java.util.Deque;
271-
import java.util.Iterator;
272-
import java.util.List;
270+
import com.oracle.truffle.api.strings.InternalByteArray;
271+
import com.oracle.truffle.api.strings.TruffleString;
273272

274273
/** A JRuby parser node visitor which translates JRuby AST nodes into truffle Nodes. */
275274
public class BodyTranslator extends BaseTranslator {
@@ -1704,7 +1703,7 @@ public RubyNode visitHashNode(HashParseNode node) {
17041703
final SourceIndexLength sourceSection = node.getPosition();
17051704

17061705
if (node.isEmpty()) { // an empty Hash literal like h = {}
1707-
final RubyNode ret = HashLiteralNode.create(RubyNode.EMPTY_ARRAY);
1706+
final RubyNode ret = HashLiteralNode.create(RubyNode.EMPTY_ARRAY, language);
17081707
ret.unsafeSetSourceSection(sourceSection);
17091708
return addNewlineIfNeeded(node, ret);
17101709
}
@@ -1717,7 +1716,7 @@ public RubyNode visitHashNode(HashParseNode node) {
17171716
// This null case is for splats {a: 1, **{b: 2}, c: 3}
17181717
if (!keyValues.isEmpty()) {
17191718
final RubyNode hashLiteralSoFar = HashLiteralNode
1720-
.create(keyValues.toArray(RubyNode.EMPTY_ARRAY));
1719+
.create(keyValues.toArray(RubyNode.EMPTY_ARRAY), language);
17211720
hashConcats.add(hashLiteralSoFar);
17221721
}
17231722
hashConcats.add(HashCastASTNodeGen.create(pair.getValue().accept(this)));
@@ -1734,7 +1733,7 @@ public RubyNode visitHashNode(HashParseNode node) {
17341733
}
17351734

17361735
if (!keyValues.isEmpty()) {
1737-
final RubyNode hashLiteralSoFar = HashLiteralNode.create(keyValues.toArray(RubyNode.EMPTY_ARRAY));
1736+
final RubyNode hashLiteralSoFar = HashLiteralNode.create(keyValues.toArray(RubyNode.EMPTY_ARRAY), language);
17381737
hashConcats.add(hashLiteralSoFar);
17391738
}
17401739

src/main/java/org/truffleruby/parser/ReloadArgumentsTranslator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public RubyNode[] reload(ArgsParseNode node) {
114114
keyValues[2 * i] = key;
115115
keyValues[2 * i + 1] = value;
116116
}
117-
kwArgsNode = HashLiteralNode.create(keyValues);
117+
kwArgsNode = HashLiteralNode.create(keyValues, language);
118118
}
119119

120120
if (node.hasKeyRest()) {

src/main/java/org/truffleruby/parser/YARPReloadArgumentsTranslator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public RubyNode[] reload(Nodes.ParametersNode parametersNode) {
9292
keyValues[2 * i] = key;
9393
keyValues[2 * i + 1] = value;
9494
}
95-
kwArgsNode = HashLiteralNode.create(keyValues);
95+
kwArgsNode = HashLiteralNode.create(keyValues, language);
9696
}
9797

9898
if (parametersNode.keyword_rest != null) {

src/main/java/org/truffleruby/parser/YARPTranslator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,7 @@ public RubyNode visitGlobalVariableTargetNode(Nodes.GlobalVariableTargetNode nod
13581358
@Override
13591359
public RubyNode visitHashNode(Nodes.HashNode node) {
13601360
if (node.elements.length == 0) { // an empty Hash literal like h = {}
1361-
final RubyNode rubyNode = HashLiteralNode.create(RubyNode.EMPTY_ARRAY);
1361+
final RubyNode rubyNode = HashLiteralNode.create(RubyNode.EMPTY_ARRAY, language);
13621362
return assignPositionAndFlags(node, rubyNode);
13631363
}
13641364

@@ -1370,7 +1370,7 @@ public RubyNode visitHashNode(Nodes.HashNode node) {
13701370
// This case is for splats {a: 1, **{b: 2}, c: 3}
13711371
if (!keyValues.isEmpty()) {
13721372
final RubyNode hashLiteralSoFar = HashLiteralNode
1373-
.create(keyValues.toArray(RubyNode.EMPTY_ARRAY));
1373+
.create(keyValues.toArray(RubyNode.EMPTY_ARRAY), language);
13741374
hashConcats.add(hashLiteralSoFar);
13751375
}
13761376
hashConcats.add(HashCastNodeGen.HashCastASTNodeGen.create(assocSplatNode.value.accept(this)));
@@ -1393,7 +1393,7 @@ public RubyNode visitHashNode(Nodes.HashNode node) {
13931393
}
13941394

13951395
if (!keyValues.isEmpty()) {
1396-
final RubyNode hashLiteralSoFar = HashLiteralNode.create(keyValues.toArray(RubyNode.EMPTY_ARRAY));
1396+
final RubyNode hashLiteralSoFar = HashLiteralNode.create(keyValues.toArray(RubyNode.EMPTY_ARRAY), language);
13971397
hashConcats.add(hashLiteralSoFar);
13981398
}
13991399

0 commit comments

Comments
 (0)