Skip to content

Commit

Permalink
checker: fix autocast in complex if condtions 2 (#18702)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Jun 29, 2023
1 parent 7ee2584 commit 60f9f53
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
20 changes: 20 additions & 0 deletions vlib/v/checker/infix.v
Expand Up @@ -17,6 +17,16 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
if node.op == .and {
mut left_node := node.left
for mut left_node is ast.InfixExpr {
if left_node.op == .and && mut left_node.right is ast.InfixExpr {
if left_node.right.op == .key_is {
// search last `n is ast.Ident` in the left
from_type := c.expr(left_node.right.left)
to_type := c.expr(left_node.right.right)
c.autocast_in_if_conds(mut node.right, left_node.right.left, from_type,
to_type)
break
}
}
if left_node.op == .key_is {
// search `n is ast.Ident`
from_type := c.expr(left_node.left)
Expand Down Expand Up @@ -835,6 +845,16 @@ fn (mut c Checker) autocast_in_if_conds(mut right ast.Expr, from_expr ast.Expr,
c.autocast_in_if_conds(mut right.right, from_expr, from_type, to_type)
}
ast.CallExpr {
if right.left.str() == from_expr.str()
&& c.table.sym(to_type).has_method_with_generic_parent(right.name) {
right.left = ast.ParExpr{
expr: ast.AsCast{
typ: to_type
expr: from_expr
expr_type: from_type
}
}
}
c.autocast_in_if_conds(mut right.left, from_expr, from_type, to_type)
for mut arg in right.args {
c.autocast_in_if_conds(mut arg.expr, from_expr, from_type, to_type)
Expand Down
45 changes: 45 additions & 0 deletions vlib/v/tests/autocast_in_if_conds_3_test.v
@@ -0,0 +1,45 @@
type MySumType = S1 | S2

struct Info {
name string
}

struct Node {
left MySumType
}

struct S1 {
is_info bool
info Info
}

fn (s1 S1) is_info() bool {
return s1.is_info
}

struct S2 {
field2 string
}

fn get_name(name string) string {
return name
}

fn test_autocast_in_if_conds() {
node := Node{
left: MySumType(S1{
is_info: false
info: Info{'foo'}
})
}

a := 22

if a > 0 && node.left is S1 && !node.left.is_info && get_name(node.left.info.name) == 'foo'
&& !node.left.is_info() {
println('ok')
assert true
} else {
assert false
}
}

0 comments on commit 60f9f53

Please sign in to comment.