all: allow using aliases as keys in map (#8589)

pull/8650/head weekly.2021.6
Swastik Baranwal 2021-02-08 23:21:05 +05:30 committed by GitHub
parent 8cb01ba8db
commit 09cff69919
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 3 deletions

View File

@ -3724,7 +3724,7 @@ fn (mut g Gen) map_init(node ast.MapInit) {
key_typ_str := g.typ(node.key_type) key_typ_str := g.typ(node.key_type)
value_typ_str := g.typ(node.value_type) value_typ_str := g.typ(node.value_type)
value_typ := g.table.get_type_symbol(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) hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_typ)
size := node.vals.len size := node.vals.len
mut shared_styp := '' // only needed for shared &[]{...} mut shared_styp := '' // only needed for shared &[]{...}

View File

@ -73,12 +73,18 @@ pub fn (mut p Parser) parse_map_type() table.Type {
} }
p.check(.lsbr) p.check(.lsbr)
key_type := p.parse_type() key_type := p.parse_type()
is_alias := p.table.get_type_symbol(key_type).kind == .alias
if key_type.idx() == 0 { if key_type.idx() == 0 {
// error is reported in parse_type // error is reported in parse_type
return 0 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())) { || ((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) 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.error_with_pos('maps only support string, integer, float, rune or voidptr keys for now (not `$s`)',
p.tok.position()) p.tok.position())

View File

@ -550,7 +550,7 @@ pub fn (t &TypeSymbol) is_pointer() bool {
[inline] [inline]
pub fn (t &TypeSymbol) is_int() bool { 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] [inline]

View File

@ -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'}"
}