diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index c8ab20210e..8ff5b6f45f 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -735,7 +735,8 @@ pub fn (mut c Checker) call_fn(call_expr mut ast.CallExpr) table.Type { } else if fn_name == 'json.decode' { expr := call_expr.args[0].expr if !(expr is ast.Type) { - c.error('json.decode: first argument needs to be a type', call_expr.pos) + typ := typeof(expr) + c.error('json.decode: first argument needs to be a type, got `$typ`', call_expr.pos) return table.void_type } typ := expr as ast.Type diff --git a/vlib/v/gen/json.v b/vlib/v/gen/json.v index abc23d0958..a224d4085f 100644 --- a/vlib/v/gen/json.v +++ b/vlib/v/gen/json.v @@ -124,7 +124,7 @@ fn (mut g Gen) decode_array(value_type table.Type) string { if is_js_prim(styp) { s = '$styp val = ${fn_name}(jsval); ' } else { - s = '\t$styp val; ${fn_name}(jsval, &val); ' + s = '\t$styp val = *($styp*) ${fn_name}(jsval).data; ' } return ' res = __new_array(0, 0, sizeof($styp)); diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 6c650847c4..e0bc65c527 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -22,7 +22,7 @@ pub fn (mut p Parser) call_expr(is_c, is_js bool, mod string) ast.CallExpr { } if fn_name == 'json.decode' { // Makes name_expr() parse the type (`User` in `json.decode(User, txt)`)` - p.inside_is = true + p.expecting_type = true p.expr_mod = '' } p.check(.lpar) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index b3b9bf54a2..76138950d7 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -42,7 +42,7 @@ mut: inside_match bool // to separate `match A { }` from `Struct{}` inside_match_case bool // to separate `match_expr { }` from `Struct{}` is_stmt_ident bool // true while the beginning of a statement is an ident/selector - inside_is bool // `is Type`, expecting type + expecting_type bool // `is Type`, expecting type } // for tests @@ -584,8 +584,8 @@ pub fn (mut p Parser) parse_ident(is_c, is_js bool) ast.Ident { pub fn (mut p Parser) name_expr() ast.Expr { mut node := ast.Expr{} - if p.inside_is { - p.inside_is = false + if p.expecting_type { + p.expecting_type = false // get type position before moving to next type_pos := p.tok.position() typ := p.parse_type() diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index 43871a2d1f..4ef6998efb 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -62,7 +62,12 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr { node = p.if_expr() } .lsbr { - node = p.array_init() + if p.expecting_type { + // parse json.decode type (`json.decode([]User, s)`) + node = p.name_expr() + } else { + node = p.array_init() + } } .key_none { p.next() @@ -190,7 +195,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr { p.next() mut right := ast.Expr{} if op == .key_is { - p.inside_is = true + p.expecting_type = true } right = p.expr(precedence) return ast.InfixExpr{