checker: implement smartcast if multi conds (part 1/2) (#10452)
parent
694b991929
commit
e5debbbe01
|
@ -5863,6 +5863,53 @@ pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) ast.Type {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut c Checker) smartcast_if_conds(node ast.Expr, mut scope ast.Scope) {
|
||||||
|
if node is ast.InfixExpr {
|
||||||
|
if node.op == .and {
|
||||||
|
c.smartcast_if_conds(node.left, mut scope)
|
||||||
|
c.smartcast_if_conds(node.right, mut scope)
|
||||||
|
} else if node.op == .key_is {
|
||||||
|
right_expr := node.right
|
||||||
|
right_type := match right_expr {
|
||||||
|
ast.TypeNode {
|
||||||
|
right_expr.typ
|
||||||
|
}
|
||||||
|
ast.None {
|
||||||
|
ast.none_type_idx
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c.error('invalid type `$right_expr`', right_expr.position())
|
||||||
|
ast.Type(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if right_type != ast.Type(0) {
|
||||||
|
left_sym := c.table.get_type_symbol(node.left_type)
|
||||||
|
expr_type := c.expr(node.left)
|
||||||
|
if left_sym.kind == .interface_ {
|
||||||
|
c.type_implements(right_type, expr_type, node.pos)
|
||||||
|
} else if !c.check_types(right_type, expr_type) {
|
||||||
|
expect_str := c.table.type_to_str(right_type)
|
||||||
|
expr_str := c.table.type_to_str(expr_type)
|
||||||
|
c.error('cannot use type `$expect_str` as type `$expr_str`', node.pos)
|
||||||
|
}
|
||||||
|
if (node.left is ast.Ident || node.left is ast.SelectorExpr)
|
||||||
|
&& node.right is ast.TypeNode {
|
||||||
|
is_variable := if mut node.left is ast.Ident {
|
||||||
|
node.left.kind == .variable
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
if is_variable {
|
||||||
|
if left_sym.kind in [.interface_, .sum_type] {
|
||||||
|
c.smartcast(node.left, node.left_type, right_type, mut scope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
|
pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
|
||||||
if_kind := if node.is_comptime { '\$if' } else { 'if' }
|
if_kind := if node.is_comptime { '\$if' } else { 'if' }
|
||||||
mut node_is_expr := false
|
mut node_is_expr := false
|
||||||
|
|
Loading…
Reference in New Issue