diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 28d287a9c8..1057bd319d 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -496,8 +496,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) } } panic('unreachable') - } - if fn_name == 'json.encode' { + } else if fn_name == 'json.encode' { } else if fn_name == 'json.decode' && node.args.len > 0 { if node.args.len != 2 { c.error("json.decode expects 2 arguments, a type and a string (e.g `json.decode(T, '')`)", @@ -506,12 +505,20 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) } expr := node.args[0].expr if expr is ast.TypeNode { - sym := c.table.sym(expr.typ) - if !c.table.known_type(sym.name) { + sym := c.table.sym(c.unwrap_generic(expr.typ)) + if c.table.known_type(sym.name) && sym.kind != .placeholder { + mut kind := sym.kind + if sym.info is ast.Alias { + kind = c.table.sym(sym.info.parent_type).kind + } + if kind !in [.struct_, .sum_type, .map, .array] { + c.error('json.decode: expected sum type, struct, map or array, found $kind', + expr.pos) + } + } else { c.error('json.decode: unknown type `$sym.name`', node.pos) } } else { - // if expr !is ast.TypeNode { typ := expr.type_name() c.error('json.decode: first argument needs to be a type, got `$typ`', node.pos) return ast.void_type diff --git a/vlib/v/checker/tests/json_decode.out b/vlib/v/checker/tests/json_decode.out new file mode 100644 index 0000000000..fd25d4651c --- /dev/null +++ b/vlib/v/checker/tests/json_decode.out @@ -0,0 +1,34 @@ +vlib/v/checker/tests/json_decode.vv:11:7: error: json.decode: unknown type `St2` + 9 | fn main() { + 10 | json.decode(St, '{a: ""}') ? // OK + 11 | json.decode(St2, '{a: ""}') ? // BAD + | ~~~~~~~~~~~~~~~~~~~~~~ + 12 | json.decode(St) ? // BAD + 13 | json.decode(string, '""') ? // BAD +vlib/v/checker/tests/json_decode.vv:12:7: error: json.decode expects 2 arguments, a type and a string (e.g `json.decode(T, '')`) + 10 | json.decode(St, '{a: ""}') ? // OK + 11 | json.decode(St2, '{a: ""}') ? // BAD + 12 | json.decode(St) ? // BAD + | ~~~~~~~~~~ + 13 | json.decode(string, '""') ? // BAD + 14 | json.decode(Num, '5') ? // BAD +vlib/v/checker/tests/json_decode.vv:13:14: error: json.decode: expected sum type, struct, map or array, found string + 11 | json.decode(St2, '{a: ""}') ? // BAD + 12 | json.decode(St) ? // BAD + 13 | json.decode(string, '""') ? // BAD + | ~~~~~~ + 14 | json.decode(Num, '5') ? // BAD + 15 | json.decode(St, 6) ? // BAD +vlib/v/checker/tests/json_decode.vv:14:14: error: json.decode: expected sum type, struct, map or array, found u8 + 12 | json.decode(St) ? // BAD + 13 | json.decode(string, '""') ? // BAD + 14 | json.decode(Num, '5') ? // BAD + | ~~~ + 15 | json.decode(St, 6) ? // BAD + 16 | } +vlib/v/checker/tests/json_decode.vv:15:7: error: json.decode: second argument needs to be a string + 13 | json.decode(string, '""') ? // BAD + 14 | json.decode(Num, '5') ? // BAD + 15 | json.decode(St, 6) ? // BAD + | ~~~~~~~~~~~~~ + 16 | } diff --git a/vlib/v/checker/tests/json_decode.vv b/vlib/v/checker/tests/json_decode.vv new file mode 100644 index 0000000000..4772e438d7 --- /dev/null +++ b/vlib/v/checker/tests/json_decode.vv @@ -0,0 +1,16 @@ +import json + +struct St { + a string +} + +type Num = u8 + +fn main() { + json.decode(St, '{a: ""}') ? // OK + json.decode(St2, '{a: ""}') ? // BAD + json.decode(St) ? // BAD + json.decode(string, '""') ? // BAD + json.decode(Num, '5') ? // BAD + json.decode(St, 6) ? // BAD +}