From 09cff699193537889b4255ef3d931cb4067abd43 Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Mon, 8 Feb 2021 23:21:05 +0530 Subject: [PATCH] all: allow using aliases as keys in map (#8589) --- vlib/v/gen/c/cgen.v | 2 +- vlib/v/parser/parse_type.v | 8 +++++++- vlib/v/table/types.v | 2 +- vlib/v/tests/map_alias_key_test.v | 22 ++++++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/map_alias_key_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index b766390ef8..393cfc2b5a 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3724,7 +3724,7 @@ fn (mut g Gen) map_init(node ast.MapInit) { key_typ_str := g.typ(node.key_type) value_typ_str := g.typ(node.value_type) value_typ := g.table.get_type_symbol(node.value_type) - key_typ := g.table.get_type_symbol(node.key_type) + key_typ := g.table.get_final_type_symbol(node.key_type) hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_typ) size := node.vals.len mut shared_styp := '' // only needed for shared &[]{...} diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 6c1fe619e2..95cdc66833 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -73,12 +73,18 @@ pub fn (mut p Parser) parse_map_type() table.Type { } p.check(.lsbr) key_type := p.parse_type() + is_alias := p.table.get_type_symbol(key_type).kind == .alias if key_type.idx() == 0 { // error is reported in parse_type return 0 } - if !(key_type in [table.string_type_idx, table.voidptr_type_idx] + if is_alias && !(key_type in [table.string_type_idx, table.voidptr_type_idx] || ((key_type.is_int() || key_type.is_float()) && !key_type.is_ptr())) { + p.error('cannot use the alias type as the parent type is unsupported') + return 0 + } + if !(key_type in [table.string_type_idx, table.voidptr_type_idx] + || ((key_type.is_int() || key_type.is_float() || is_alias) && !key_type.is_ptr())) { s := p.table.type_to_str(key_type) p.error_with_pos('maps only support string, integer, float, rune or voidptr keys for now (not `$s`)', p.tok.position()) diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index 6d0a03a50a..136e093225 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -550,7 +550,7 @@ pub fn (t &TypeSymbol) is_pointer() bool { [inline] pub fn (t &TypeSymbol) is_int() bool { - return t.kind in [.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .int_literal] + return t.kind in [.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .int_literal, .rune] } [inline] diff --git a/vlib/v/tests/map_alias_key_test.v b/vlib/v/tests/map_alias_key_test.v new file mode 100644 index 0000000000..91c750aea0 --- /dev/null +++ b/vlib/v/tests/map_alias_key_test.v @@ -0,0 +1,22 @@ +type Type = int +type RType = rune + +fn test_map_key_alias() { + mut m_int := map{12: '12', 2: '2'} + m_int[14] = '14' + m_int[Type(15)] = '15' + assert m_int.str() == "{12: '12', 2: '2', 14: '14', 15: '15'}" + //// /// ///// // + mut m_rune := map{`a`: '12', `l`: '14'} + m_rune[`g`] = '12' + m_rune[RType(`$`)] = '16' + assert m_rune.str() == "{`a`: '12', `l`: '14', `g`: '12', `$`: '16'}" +} + +fn test_map_alias_key_init() { + m_int := map{Type(12): '12', Type(2): '2'} + assert m_int.str() == "{12: '12', 2: '2'}" + //// // ///// // + m_rune := map{RType(`a`): '12', RType(`l`): '14'} + assert m_rune.str() == "{`a`: '12', `l`: '14'}" +}