mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: fix autocast in complex if condtions 2 (#18702)
This commit is contained in:
parent
7ee25843c2
commit
60f9f53e36
@ -17,6 +17,16 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
|||||||
if node.op == .and {
|
if node.op == .and {
|
||||||
mut left_node := node.left
|
mut left_node := node.left
|
||||||
for mut left_node is ast.InfixExpr {
|
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 {
|
if left_node.op == .key_is {
|
||||||
// search `n is ast.Ident`
|
// search `n is ast.Ident`
|
||||||
from_type := c.expr(left_node.left)
|
from_type := c.expr(left_node.left)
|
||||||
@ -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)
|
c.autocast_in_if_conds(mut right.right, from_expr, from_type, to_type)
|
||||||
}
|
}
|
||||||
ast.CallExpr {
|
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)
|
c.autocast_in_if_conds(mut right.left, from_expr, from_type, to_type)
|
||||||
for mut arg in right.args {
|
for mut arg in right.args {
|
||||||
c.autocast_in_if_conds(mut arg.expr, from_expr, from_type, to_type)
|
c.autocast_in_if_conds(mut arg.expr, from_expr, from_type, to_type)
|
||||||
|
45
vlib/v/tests/autocast_in_if_conds_3_test.v
Normal file
45
vlib/v/tests/autocast_in_if_conds_3_test.v
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user