Skip to content

Commit 0132814

Browse files
authored
cgen: fix hash functions for map[Enum]Value, and enum Enum as u64 { (fix #23630) (#23632)
1 parent f291ed8 commit 0132814

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

vlib/v/gen/c/cgen.v

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3328,14 +3328,14 @@ fn (mut g Gen) gen_clone_assignment(var_type ast.Type, val ast.Expr, typ ast.Typ
33283328
return true
33293329
}
33303330

3331-
fn (mut g Gen) map_fn_ptrs(key_typ ast.TypeSymbol) (string, string, string, string) {
3331+
fn (mut g Gen) map_fn_ptrs(key_sym ast.TypeSymbol) (string, string, string, string) {
33323332
mut hash_fn := ''
33333333
mut key_eq_fn := ''
33343334
mut clone_fn := ''
33353335
mut free_fn := '&map_free_nop'
3336-
match key_typ.kind {
3336+
match key_sym.kind {
33373337
.alias {
3338-
alias_key_type := (key_typ.info as ast.Alias).parent_type
3338+
alias_key_type := (key_sym.info as ast.Alias).parent_type
33393339
return g.map_fn_ptrs(g.table.sym(alias_key_type))
33403340
}
33413341
.u8, .i8, .char {
@@ -3348,8 +3348,11 @@ fn (mut g Gen) map_fn_ptrs(key_typ ast.TypeSymbol) (string, string, string, stri
33483348
key_eq_fn = '&map_eq_int_2'
33493349
clone_fn = '&map_clone_int_2'
33503350
}
3351-
.int, .i32, .u32, .rune, .f32, .enum {
3352-
// XTODO i64
3351+
.enum {
3352+
einfo := (key_sym.info) as ast.Enum
3353+
return g.map_fn_ptrs(g.table.sym(einfo.typ))
3354+
}
3355+
.int, .i32, .u32, .rune, .f32 {
33533356
hash_fn = '&map_hash_int_4'
33543357
key_eq_fn = '&map_eq_int_4'
33553358
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
33743377
free_fn = '&map_free_string'
33753378
}
33763379
else {
3377-
verror('map key type `${key_typ.name}` not supported')
3380+
verror('map key type `${key_sym.name}` not supported')
33783381
}
33793382
}
33803383
return hash_fn, key_eq_fn, clone_fn, free_fn
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// vfmt off
2+
@[flag]
3+
enum Bits8 as u8 {
4+
a1 b1 c1 d1 e1 f1 g1 h1
5+
}
6+
@[flag]
7+
enum Bits16 as u16 {
8+
a1 b1 c1 d1 e1 f1 g1 h1
9+
a2 b2 c2 d2 e2 f2 g2 h2
10+
}
11+
@[flag]
12+
enum Bits32 as u32 {
13+
a1 b1 c1 d1 e1 f1 g1 h1
14+
a2 b2 c2 d2 e2 f2 g2 h2
15+
a3 b3 c3 d3 e3 f3 g3 h3
16+
a4 b4 c4 d4 e4 f4 g4 h4
17+
}
18+
@[flag]
19+
enum Bits64 as u64 {
20+
a1 b1 c1 d1 e1 f1 g1 h1
21+
a2 b2 c2 d2 e2 f2 g2 h2
22+
a3 b3 c3 d3 e3 f3 g3 h3
23+
a4 b4 c4 d4 e4 f4 g4 h4
24+
a5 b5 c5 d5 e5 f5 g5 h5
25+
a6 b6 c6 d6 e6 f6 g6 h6
26+
a7 b7 c7 d7 e7 f7 g7 h7
27+
a8 b8 c8 d8 e8 f8 g8 h8
28+
}
29+
// vfmt on
30+
31+
fn check_map[T](size int) {
32+
println('>>> checking map of ${T.name:10} enum keys, size should be: ${size}')
33+
mut m := map[T]u32{}
34+
for i in 0 .. size {
35+
n := u64(1) << i
36+
m[unsafe { T(n) }] = i
37+
// eprintln('>>> i: ${i:2} | n: ${n:20} | m.len: ${m.len}')
38+
}
39+
assert m.len == size
40+
}
41+
42+
fn test_maps_with_enum_keys_work() {
43+
check_map[Bits8](8)
44+
check_map[Bits16](16)
45+
check_map[Bits32](32)
46+
check_map[Bits64](64)
47+
}

0 commit comments

Comments
 (0)