summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y34
1 files changed, 33 insertions, 1 deletions
diff --git a/parse.y b/parse.y
index e669adbcd5..0b69bc1d7e 100644
--- a/parse.y
+++ b/parse.y
@@ -12184,10 +12184,42 @@ append_literal_keys(st_data_t k, st_data_t v, st_data_t h)
return ST_CONTINUE;
}
+static bool
+hash_literal_key_p(VALUE k)
+{
+ switch (OBJ_BUILTIN_TYPE(k)) {
+ case T_NODE:
+ case T_REGEXP:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static int
+literal_cmp(VALUE val, VALUE lit)
+{
+ if (val == lit) return 0;
+ if (!hash_literal_key_p(val) || !hash_literal_key_p(lit)) return -1;
+ return rb_iseq_cdhash_cmp(val, lit);
+}
+
+static st_index_t
+literal_hash(VALUE a)
+{
+ if (!hash_literal_key_p(a)) return (st_index_t)a;
+ return rb_iseq_cdhash_hash(a);
+}
+
+static const struct st_hash_type literal_type = {
+ literal_cmp,
+ literal_hash,
+};
+
static NODE *
remove_duplicate_keys(struct parser_params *p, NODE *hash)
{
- st_table *literal_keys = st_init_numtable_with_size(hash->nd_alen / 2);
+ st_table *literal_keys = st_init_table_with_size(&literal_type, hash->nd_alen / 2);
NODE *result = 0;
rb_code_location_t loc = hash->nd_loc;
while (hash && hash->nd_head && hash->nd_next) {