checker: check match condition

pull/4716/head
Alexander Medvednikov 2020-05-04 21:03:18 +02:00
parent 9823d80e0c
commit 9aa1a65489
2 changed files with 10 additions and 9 deletions

View File

@ -8,7 +8,7 @@ struct Employee {
fn test_simple() { fn test_simple() {
x := Employee{'Peter', 28} x := Employee{'Peter', 28}
s := json.encode(x) s := json.encode(x)
assert s == '{"name":"Peter","age":28}' assert s == '{"name":"Peter","age":28}'
y := json.decode(Employee, s) or { y := json.decode(Employee, s) or {
assert false assert false
} }

View File

@ -658,16 +658,13 @@ pub fn (mut c Checker) call_method(call_expr mut ast.CallExpr) table.Type {
// call_expr.args << method.args[0].typ // call_expr.args << method.args[0].typ
// call_expr.exp_arg_types << method.args[0].typ // call_expr.exp_arg_types << method.args[0].typ
for i, arg in call_expr.args { for i, arg in call_expr.args {
exp_arg_typ := if method.is_variadic && i >= method.args.len - 1 { exp_arg_typ := if method.is_variadic && i >= method.args.len - 1 { method.args[method.args.len -
method.args[method.args.len - 1].typ 1].typ } else { method.args[i + 1].typ }
} else {
method.args[i + 1].typ
}
c.expected_type = exp_arg_typ c.expected_type = exp_arg_typ
got_arg_typ := c.expr(arg.expr) got_arg_typ := c.expr(arg.expr)
call_expr.args[i].typ = got_arg_typ call_expr.args[i].typ = got_arg_typ
if method.is_variadic && got_arg_typ.flag_is(.variadic) && call_expr.args.len - 1 > if method.is_variadic && got_arg_typ.flag_is(.variadic) && call_expr.args.len -
i { 1 > i {
c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos) c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos)
} }
if !c.table.check(got_arg_typ, exp_arg_typ) { if !c.table.check(got_arg_typ, exp_arg_typ) {
@ -1752,6 +1749,10 @@ pub fn (mut c Checker) match_expr(node mut ast.MatchExpr) table.Type {
c.expected_type = cond_type c.expected_type = cond_type
typ := c.expr(expr) typ := c.expr(expr)
typ_sym := c.table.get_type_symbol(typ) typ_sym := c.table.get_type_symbol(typ)
if !node.is_sum_type && !c.table.check(typ, cond_type) {
exp_sym := c.table.get_type_symbol(cond_type)
c.error('cannot use `$typ_sym.name` as `$exp_sym.name` in `match`', node.pos)
}
// TODO: // TODO:
if typ_sym.kind == .sum_type { if typ_sym.kind == .sum_type {
} }
@ -1787,7 +1788,7 @@ pub fn (mut c Checker) match_expr(node mut ast.MatchExpr) table.Type {
fn (mut c Checker) match_exprs(node mut ast.MatchExpr, type_sym table.TypeSymbol) { fn (mut c Checker) match_exprs(node mut ast.MatchExpr, type_sym table.TypeSymbol) {
// branch_exprs is a histogram of how many times // branch_exprs is a histogram of how many times
// an expr was used in the match // an expr was used in the match
mut branch_exprs := map[string]int mut branch_exprs := map[string]int{}
for branch in node.branches { for branch in node.branches {
for expr in branch.exprs { for expr in branch.exprs {
mut key := '' mut key := ''