mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
v: use autocasting in complex conditions (#18797)
This commit is contained in:
parent
b3f89e1417
commit
2d838d5178
@ -454,8 +454,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||
// TODO: and remove the less strict check from above.
|
||||
if left_sym.kind == .array && !c.inside_unsafe && right_sym.kind == .array
|
||||
&& left is ast.Ident && !left.is_blank_ident() && right in [ast.Ident, ast.SelectorExpr]
|
||||
&& ((node.op == .decl_assign && (left as ast.Ident).is_mut)
|
||||
|| node.op == .assign) {
|
||||
&& ((node.op == .decl_assign && left.is_mut) || node.op == .assign) {
|
||||
// no point to show the notice, if the old error was already shown:
|
||||
if !old_assign_error_condition {
|
||||
mut_str := if node.op == .decl_assign { 'mut ' } else { '' }
|
||||
@ -498,7 +497,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||
c.error('unkown return type: cannot assign `${right}` as a function variable',
|
||||
right.pos())
|
||||
} else if (!right_sym.info.is_anon && return_sym.kind == .any)
|
||||
|| (return_sym.info is ast.Struct && (return_sym.info as ast.Struct).is_generic) {
|
||||
|| (return_sym.info is ast.Struct && return_sym.info.is_generic) {
|
||||
c.error('cannot assign `${right}` as a generic function variable', right.pos())
|
||||
}
|
||||
}
|
||||
|
@ -2248,7 +2248,7 @@ pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) {
|
||||
f.comments(node.before_op_comments, iembed: node.before_op_comments[0].is_inline)
|
||||
}
|
||||
is_one_val_array_init := node.op in [.key_in, .not_in] && node.right is ast.ArrayInit
|
||||
&& (node.right as ast.ArrayInit).exprs.len == 1
|
||||
&& node.right.exprs.len == 1
|
||||
is_and := node.op == .amp && f.node_str(node.right).starts_with('&')
|
||||
if is_one_val_array_init && !f.inside_comptime_if {
|
||||
// `var in [val]` => `var == val`
|
||||
|
@ -33,8 +33,7 @@ fn (mut g Gen) expr_with_opt_or_block(expr ast.Expr, expr_typ ast.Type, var_expr
|
||||
stmts := (expr as ast.Ident).or_expr.stmts
|
||||
// handles stmt block which returns something
|
||||
// e.g. { return none }
|
||||
if stmts.len > 0 && stmts.last() is ast.ExprStmt
|
||||
&& (stmts.last() as ast.ExprStmt).typ != ast.void_type {
|
||||
if stmts.len > 0 && stmts.last() is ast.ExprStmt && stmts.last().typ != ast.void_type {
|
||||
g.gen_or_block_stmts(var_expr.str(), '', stmts, ret_typ, false)
|
||||
} else {
|
||||
// handles stmt block which doesn't returns value
|
||||
@ -265,7 +264,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
||||
var_type = val_type.clear_flag(.option)
|
||||
left.obj.typ = var_type
|
||||
}
|
||||
} else if val is ast.DumpExpr && (val as ast.DumpExpr).expr is ast.ComptimeSelector {
|
||||
} else if val is ast.DumpExpr && val.expr is ast.ComptimeSelector {
|
||||
key_str := g.get_comptime_selector_key_type(val.expr as ast.ComptimeSelector)
|
||||
if key_str != '' {
|
||||
var_type = g.comptime_var_type_map[key_str] or { var_type }
|
||||
@ -273,8 +272,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
||||
left.obj.typ = var_type
|
||||
}
|
||||
} else if val is ast.IndexExpr {
|
||||
if val.left is ast.Ident && g.is_generic_param_var((val as ast.IndexExpr).left) {
|
||||
ctyp := g.unwrap_generic(g.get_gn_var_type((val as ast.IndexExpr).left as ast.Ident))
|
||||
if val.left is ast.Ident && g.is_generic_param_var(val.left) {
|
||||
ctyp := g.unwrap_generic(g.get_gn_var_type(val.left as ast.Ident))
|
||||
if ctyp != ast.void_type {
|
||||
var_type = ctyp
|
||||
val_type = var_type
|
||||
@ -360,10 +359,9 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
||||
unaliased_right_sym := g.table.final_sym(unwrapped_val_type)
|
||||
is_fixed_array_var := unaliased_right_sym.kind == .array_fixed && val !is ast.ArrayInit
|
||||
&& (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.DumpExpr]
|
||||
|| (val is ast.CastExpr && (val as ast.CastExpr).expr !is ast.ArrayInit)
|
||||
|| (val is ast.PrefixExpr && (val as ast.PrefixExpr).op == .arrow)
|
||||
|| (val is ast.UnsafeExpr && (val as ast.UnsafeExpr).expr is ast.Ident))
|
||||
&& !g.pref.translated
|
||||
|| (val is ast.CastExpr && val.expr !is ast.ArrayInit)
|
||||
|| (val is ast.PrefixExpr && val.op == .arrow)
|
||||
|| (val is ast.UnsafeExpr && val.expr is ast.Ident)) && !g.pref.translated
|
||||
g.is_assign_lhs = true
|
||||
g.assign_op = node.op
|
||||
|
||||
@ -572,7 +570,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
||||
}
|
||||
if !is_used_var_styp {
|
||||
if !val_type.has_flag(.option) && left_sym.info is ast.ArrayFixed
|
||||
&& (left_sym.info as ast.ArrayFixed).is_fn_ret {
|
||||
&& left_sym.info.is_fn_ret {
|
||||
g.write('${styp[3..]} ')
|
||||
} else {
|
||||
g.write('${styp} ')
|
||||
@ -668,7 +666,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
||||
g.write('{0}')
|
||||
}
|
||||
} else {
|
||||
is_option_unwrapped := (val is ast.Ident && val.or_expr.kind != .absent)
|
||||
is_option_unwrapped := val is ast.Ident && val.or_expr.kind != .absent
|
||||
is_option_auto_heap := is_auto_heap && is_option_unwrapped
|
||||
if is_auto_heap {
|
||||
g.write('HEAP(${styp}, (')
|
||||
@ -694,7 +692,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
||||
// var = &auto_heap_var
|
||||
old_is_auto_heap := g.is_option_auto_heap
|
||||
g.is_option_auto_heap = val_type.has_flag(.option) && val is ast.PrefixExpr
|
||||
&& (val as ast.PrefixExpr).right is ast.Ident
|
||||
&& val.right is ast.Ident
|
||||
&& ((val as ast.PrefixExpr).right as ast.Ident).is_auto_heap()
|
||||
defer {
|
||||
g.is_option_auto_heap = old_is_auto_heap
|
||||
@ -739,7 +737,7 @@ fn (mut g Gen) gen_multi_return_assign(node &ast.AssignStmt, return_type ast.Typ
|
||||
mr_var_name := 'mr_${node.pos.pos}'
|
||||
mut is_option := return_type.has_flag(.option)
|
||||
mut mr_styp := g.typ(return_type.clear_flag(.result))
|
||||
if node.right[0] is ast.CallExpr && (node.right[0] as ast.CallExpr).or_block.kind != .absent {
|
||||
if node.right[0] is ast.CallExpr && node.right[0].or_block.kind != .absent {
|
||||
is_option = false
|
||||
mr_styp = g.typ(return_type.clear_flags(.option, .result))
|
||||
}
|
||||
|
@ -3308,8 +3308,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
|
||||
} else if node.op == .question {
|
||||
cur_line := g.go_before_stmt(0).trim_space()
|
||||
mut expr_str := ''
|
||||
if mut node.expr is ast.ComptimeSelector
|
||||
&& (node.expr as ast.ComptimeSelector).left is ast.Ident {
|
||||
if mut node.expr is ast.ComptimeSelector && node.expr.left is ast.Ident {
|
||||
// val.$(field.name)?
|
||||
expr_str = '${node.expr.left.str()}.${g.comptime_for_field_value.name}'
|
||||
} else if mut node.expr is ast.Ident && g.is_comptime_var(node.expr) {
|
||||
@ -3719,8 +3718,8 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
||||
}
|
||||
}
|
||||
// var?.field_opt
|
||||
field_is_opt := (node.expr is ast.Ident && node.expr.is_auto_heap()
|
||||
&& node.expr.or_expr.kind != .absent && field_typ.has_flag(.option))
|
||||
field_is_opt := node.expr is ast.Ident && node.expr.is_auto_heap()
|
||||
&& node.expr.or_expr.kind != .absent && field_typ.has_flag(.option)
|
||||
if field_is_opt {
|
||||
g.write('((${g.base_type(field_typ)})')
|
||||
}
|
||||
@ -4194,14 +4193,14 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
|
||||
|
||||
[inline]
|
||||
pub fn (mut g Gen) is_generic_param_var(node ast.Expr) bool {
|
||||
return node is ast.Ident && node.info is ast.IdentVar
|
||||
&& (node as ast.Ident).obj is ast.Var && ((node as ast.Ident).obj as ast.Var).ct_type_var == .generic_param
|
||||
return node is ast.Ident && node.info is ast.IdentVar && node.obj is ast.Var
|
||||
&& ((node as ast.Ident).obj as ast.Var).ct_type_var == .generic_param
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (mut g Gen) is_comptime_var(node ast.Expr) bool {
|
||||
return node is ast.Ident && node.info is ast.IdentVar
|
||||
&& (node as ast.Ident).obj is ast.Var && ((node as ast.Ident).obj as ast.Var).ct_type_var != .no_comptime
|
||||
return node is ast.Ident && node.info is ast.IdentVar && node.obj is ast.Var
|
||||
&& ((node as ast.Ident).obj as ast.Var).ct_type_var != .no_comptime
|
||||
}
|
||||
|
||||
fn (mut g Gen) ident(node ast.Ident) {
|
||||
@ -4733,7 +4732,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
|
||||
if node.exprs.len > 0 {
|
||||
// skip `return $vweb.html()`
|
||||
if node.exprs[0] is ast.ComptimeCall && (node.exprs[0] as ast.ComptimeCall).is_vweb {
|
||||
if node.exprs[0] is ast.ComptimeCall && node.exprs[0].is_vweb {
|
||||
g.inside_return_tmpl = true
|
||||
g.expr(node.exprs[0])
|
||||
g.inside_return_tmpl = false
|
||||
@ -5487,7 +5486,7 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) {
|
||||
if g.pref.translated {
|
||||
def_builder.write_string(' = ${g.expr_string(field.expr)}')
|
||||
} else if (field.expr.is_literal() && should_init) || cinit
|
||||
|| (field.expr is ast.ArrayInit && (field.expr as ast.ArrayInit).is_fixed)
|
||||
|| (field.expr is ast.ArrayInit && field.expr.is_fixed)
|
||||
|| (is_simple_unsafe_expr && should_init) {
|
||||
// Simple literals can be initialized right away in global scope in C.
|
||||
// e.g. `int myglobal = 10;`
|
||||
@ -6126,8 +6125,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
|
||||
g.inside_or_block = false
|
||||
}
|
||||
stmts := or_block.stmts
|
||||
if stmts.len > 0 && stmts.last() is ast.ExprStmt
|
||||
&& (stmts.last() as ast.ExprStmt).typ != ast.void_type {
|
||||
if stmts.len > 0 && stmts.last() is ast.ExprStmt && stmts.last().typ != ast.void_type {
|
||||
g.gen_or_block_stmts(cvar_name, mr_styp, stmts, return_type, true)
|
||||
} else {
|
||||
g.stmts(stmts)
|
||||
|
@ -749,7 +749,7 @@ fn (mut g Gen) pop_existing_comptime_values() {
|
||||
[inline]
|
||||
fn (mut g Gen) is_comptime_selector_field_name(node ast.SelectorExpr, field_name string) bool {
|
||||
return g.inside_comptime_for_field && node.expr is ast.Ident
|
||||
&& (node.expr as ast.Ident).name == g.comptime_for_field_var && node.field_name == field_name
|
||||
&& node.expr.name == g.comptime_for_field_var && node.field_name == field_name
|
||||
}
|
||||
|
||||
// check_comptime_is_field_selector checks if the SelectorExpr is related to $for variable accessing .typ field
|
||||
@ -786,7 +786,7 @@ fn (mut g Gen) get_comptime_var_type(node ast.Expr) ast.Type {
|
||||
if key_str != '' {
|
||||
return g.comptime_var_type_map[key_str] or { ast.void_type }
|
||||
}
|
||||
} else if node is ast.SelectorExpr && g.is_comptime_selector_type(node as ast.SelectorExpr) {
|
||||
} else if node is ast.SelectorExpr && g.is_comptime_selector_type(node) {
|
||||
// field_var.typ from $for field
|
||||
return g.comptime_for_field_type
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||
g.gen_plain_infix_expr(node)
|
||||
} else if (left.typ.idx() == ast.string_type_idx || (!has_defined_eq_operator
|
||||
&& left.unaliased.idx() == ast.string_type_idx)) && node.right is ast.StringLiteral
|
||||
&& (node.right as ast.StringLiteral).val == '' {
|
||||
&& node.right.val == '' {
|
||||
// `str == ''` -> `str.len == 0` optimization
|
||||
g.write('(')
|
||||
g.expr(node.left)
|
||||
|
@ -253,7 +253,7 @@ fn (mut g Gen) match_expr_switch(node ast.MatchExpr, is_expr bool, cond_var stri
|
||||
|
||||
mut covered_enum_cap := 0
|
||||
if cond_fsym.info is ast.Enum {
|
||||
covered_enum_cap = (cond_fsym.info as ast.Enum).vals.len
|
||||
covered_enum_cap = cond_fsym.info.vals.len
|
||||
}
|
||||
mut covered_enum := []string{cap: covered_enum_cap} // collects missing enum variant branches to avoid cstrict errors
|
||||
|
||||
@ -268,7 +268,7 @@ fn (mut g Gen) match_expr_switch(node ast.MatchExpr, is_expr bool, cond_var stri
|
||||
for branch in node.branches {
|
||||
if branch.is_else {
|
||||
if cond_fsym.info is ast.Enum {
|
||||
for val in (cond_fsym.info as ast.Enum).vals {
|
||||
for val in cond_fsym.info.vals {
|
||||
if val !in covered_enum {
|
||||
g.writeln('case ${cname}${val}:')
|
||||
}
|
||||
|
@ -715,8 +715,8 @@ fn expr_is_single_line(expr ast.Expr) bool {
|
||||
pub fn (mut f Gen) assert_stmt(node ast.AssertStmt) {
|
||||
f.write('assert ')
|
||||
mut expr := node.expr
|
||||
for expr is ast.ParExpr {
|
||||
expr = (expr as ast.ParExpr).expr
|
||||
for mut expr is ast.ParExpr {
|
||||
expr = expr.expr
|
||||
}
|
||||
f.expr(expr)
|
||||
f.writeln('')
|
||||
|
@ -475,7 +475,7 @@ fn (mut p Parser) parse_type() ast.Type {
|
||||
return 0
|
||||
}
|
||||
sym := p.table.sym(typ)
|
||||
if is_option && sym.info is ast.SumType && (sym.info as ast.SumType).is_anon {
|
||||
if is_option && sym.info is ast.SumType && sym.info.is_anon {
|
||||
p.error_with_pos('an inline sum type cannot be an Option', option_pos.extend(p.prev_tok.pos()))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user