From 87c0a9ce2812fafd603b92dd96406d77dc1ac189 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Wed, 1 Jan 2025 20:48:50 -0300 Subject: [PATCH] checker: fix comptime indexexpr resolving (#23333) --- vlib/v/checker/fn.v | 8 ++++ vlib/v/gen/c/fn.v | 8 ++++ vlib/x/json2/decoder.v | 4 +- vlib/x/json2/json2.v | 18 +++++++++ vlib/x/json2/tests/decode_nested_array_test.v | 39 +++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 vlib/x/json2/tests/decode_nested_array_test.v diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index bf2287c0354a1b..d2a2d47762c857 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -2043,6 +2043,14 @@ fn (mut c Checker) resolve_comptime_args(func &ast.Fn, node_ ast.CallExpr, concr } } else if call_arg.expr is ast.ComptimeCall { comptime_args[k] = c.type_resolver.get_type(call_arg.expr) + } else if call_arg.expr is ast.IndexExpr && c.comptime.is_comptime(call_arg.expr) { + mut ctyp := c.type_resolver.get_type(call_arg.expr) + param_typ_sym := c.table.sym(param_typ) + cparam_type_sym := c.table.sym(c.unwrap_generic(ctyp)) + if param_typ_sym.kind == .array && cparam_type_sym.info is ast.Array { + ctyp = cparam_type_sym.info.elem_type + } + comptime_args[k] = ctyp } } } diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 9342347b2c43e8..19716b4d46813c 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1659,6 +1659,14 @@ fn (mut g Gen) resolve_comptime_args(func &ast.Fn, mut node_ ast.CallExpr, concr comptime_args[k] = cparam_type_sym.info.key_type comptime_args[k + 1] = cparam_type_sym.info.value_type } + } else if mut call_arg.expr is ast.IndexExpr && g.comptime.is_comptime(call_arg.expr) { + mut ctyp := g.type_resolver.get_type(call_arg.expr) + param_typ_sym := g.table.sym(param_typ) + cparam_type_sym := g.table.sym(g.unwrap_generic(ctyp)) + if param_typ_sym.kind == .array && cparam_type_sym.info is ast.Array { + ctyp = cparam_type_sym.info.elem_type + } + comptime_args[k] = ctyp } } } diff --git a/vlib/x/json2/decoder.v b/vlib/x/json2/decoder.v index 5ffa6db122783a..431b366d3524a1 100644 --- a/vlib/x/json2/decoder.v +++ b/vlib/x/json2/decoder.v @@ -291,8 +291,8 @@ fn decode_array_item[T](mut field T, arr []Any) { $else $if T is [][]?u64 { field << arr.map(it.as_map().values().map(?u64(it.u64()))) } $else $if T is [][]bool { field << arr.map(it.as_map().values().map(it.bool())) } $else $if T is [][]?bool { field << arr.map(it.as_map().values().map(?bool(it.bool()))) } - $else $if T is [][]string { field << arr.map(it.as_map().values().map(it.string())) } - $else $if T is [][]?string { field << arr.map(it.as_map().values().map(?string(it.string()))) } + $else $if T is [][]string { field << arr.map(it.as_map().values().map(it.str())) } + $else $if T is [][]?string { field << arr.map(it.as_map().values().map(?string(it.str()))) } } } // vfmt on diff --git a/vlib/x/json2/json2.v b/vlib/x/json2/json2.v index b135639b38ab22..9cf49d935b4195 100644 --- a/vlib/x/json2/json2.v +++ b/vlib/x/json2/json2.v @@ -95,6 +95,24 @@ pub fn (f Any) i64() i64 { } } +// u8 uses `Any` as a 8-bit unsigned integer. +pub fn (f Any) u8() u8 { + match f { + u8 { + return f + } + u16, u32, i8, i16, i32, int, i64, f32, f64, bool { + return u8(u16(f)) + } + string { + return f.u8() + } + else { + return 0 + } + } +} + // u64 uses `Any` as a 64-bit unsigned integer. pub fn (f Any) u64() u64 { match f { diff --git a/vlib/x/json2/tests/decode_nested_array_test.v b/vlib/x/json2/tests/decode_nested_array_test.v new file mode 100644 index 00000000000000..68809ccc0fadcc --- /dev/null +++ b/vlib/x/json2/tests/decode_nested_array_test.v @@ -0,0 +1,39 @@ +import x.json2 + +struct Dataset { + values [][]string +} + +struct Dataset2 { + values [][]u8 +} + +fn test_string() { + d := Dataset{ + values: [ + ['a', 'b', 'c'], + ['d', 'e', 'f'], + ] + } + s := json2.encode(d) + println(s) + d2 := json2.decode[Dataset](s)! + assert d2.str() == "Dataset{ + values: [['a', 'b', 'c'], ['d', 'e', 'f']] +}" +} + +fn test_u8() { + d := Dataset2{ + values: [ + [u8(1), 2, 3, 4, 5], + [u8(2), 3, 4, 5, 6], + ] + } + s := json2.encode(d) + println(s) + d2 := json2.decode[Dataset2](s)! + assert d2.str() == 'Dataset2{ + values: [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6]] +}' +}