diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index e90d7ccffb..2eb95641f3 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3328,14 +3328,14 @@ fn (mut g Gen) gen_clone_assignment(var_type ast.Type, val ast.Expr, typ ast.Typ return true } -fn (mut g Gen) map_fn_ptrs(key_typ ast.TypeSymbol) (string, string, string, string) { +fn (mut g Gen) map_fn_ptrs(key_sym ast.TypeSymbol) (string, string, string, string) { mut hash_fn := '' mut key_eq_fn := '' mut clone_fn := '' mut free_fn := '&map_free_nop' - match key_typ.kind { + match key_sym.kind { .alias { - alias_key_type := (key_typ.info as ast.Alias).parent_type + alias_key_type := (key_sym.info as ast.Alias).parent_type return g.map_fn_ptrs(g.table.sym(alias_key_type)) } .u8, .i8, .char { @@ -3348,8 +3348,11 @@ fn (mut g Gen) map_fn_ptrs(key_typ ast.TypeSymbol) (string, string, string, stri key_eq_fn = '&map_eq_int_2' clone_fn = '&map_clone_int_2' } - .int, .i32, .u32, .rune, .f32, .enum { - // XTODO i64 + .enum { + einfo := (key_sym.info) as ast.Enum + return g.map_fn_ptrs(g.table.sym(einfo.typ)) + } + .int, .i32, .u32, .rune, .f32 { hash_fn = '&map_hash_int_4' key_eq_fn = '&map_eq_int_4' clone_fn = '&map_clone_int_4' @@ -3374,7 +3377,7 @@ fn (mut g Gen) map_fn_ptrs(key_typ ast.TypeSymbol) (string, string, string, stri free_fn = '&map_free_string' } else { - verror('map key type `${key_typ.name}` not supported') + verror('map key type `${key_sym.name}` not supported') } } return hash_fn, key_eq_fn, clone_fn, free_fn diff --git a/vlib/v/tests/enums/maps_with_enum_flag_keys_test.v b/vlib/v/tests/enums/maps_with_enum_flag_keys_test.v new file mode 100644 index 0000000000..476c001d17 --- /dev/null +++ b/vlib/v/tests/enums/maps_with_enum_flag_keys_test.v @@ -0,0 +1,47 @@ +// vfmt off +@[flag] +enum Bits8 as u8 { + a1 b1 c1 d1 e1 f1 g1 h1 +} +@[flag] +enum Bits16 as u16 { + a1 b1 c1 d1 e1 f1 g1 h1 + a2 b2 c2 d2 e2 f2 g2 h2 +} +@[flag] +enum Bits32 as u32 { + a1 b1 c1 d1 e1 f1 g1 h1 + a2 b2 c2 d2 e2 f2 g2 h2 + a3 b3 c3 d3 e3 f3 g3 h3 + a4 b4 c4 d4 e4 f4 g4 h4 +} +@[flag] +enum Bits64 as u64 { + a1 b1 c1 d1 e1 f1 g1 h1 + a2 b2 c2 d2 e2 f2 g2 h2 + a3 b3 c3 d3 e3 f3 g3 h3 + a4 b4 c4 d4 e4 f4 g4 h4 + a5 b5 c5 d5 e5 f5 g5 h5 + a6 b6 c6 d6 e6 f6 g6 h6 + a7 b7 c7 d7 e7 f7 g7 h7 + a8 b8 c8 d8 e8 f8 g8 h8 +} +// vfmt on + +fn check_map[T](size int) { + println('>>> checking map of ${T.name:10} enum keys, size should be: ${size}') + mut m := map[T]u32{} + for i in 0 .. size { + n := u64(1) << i + m[unsafe { T(n) }] = i + // eprintln('>>> i: ${i:2} | n: ${n:20} | m.len: ${m.len}') + } + assert m.len == size +} + +fn test_maps_with_enum_keys_work() { + check_map[Bits8](8) + check_map[Bits16](16) + check_map[Bits32](32) + check_map[Bits64](64) +}