diff options
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 34 |
1 files changed, 33 insertions, 1 deletions
@@ -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) { |