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.
|
// TODO: and remove the less strict check from above.
|
||||||
if left_sym.kind == .array && !c.inside_unsafe && right_sym.kind == .array
|
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]
|
&& 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 == .decl_assign && left.is_mut) || node.op == .assign) {
|
||||||
|| node.op == .assign) {
|
|
||||||
// no point to show the notice, if the old error was already shown:
|
// no point to show the notice, if the old error was already shown:
|
||||||
if !old_assign_error_condition {
|
if !old_assign_error_condition {
|
||||||
mut_str := if node.op == .decl_assign { 'mut ' } else { '' }
|
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',
|
c.error('unkown return type: cannot assign `${right}` as a function variable',
|
||||||
right.pos())
|
right.pos())
|
||||||
} else if (!right_sym.info.is_anon && return_sym.kind == .any)
|
} 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())
|
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)
|
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
|
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('&')
|
is_and := node.op == .amp && f.node_str(node.right).starts_with('&')
|
||||||
if is_one_val_array_init && !f.inside_comptime_if {
|
if is_one_val_array_init && !f.inside_comptime_if {
|
||||||
// `var in [val]` => `var == val`
|
// `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
|
stmts := (expr as ast.Ident).or_expr.stmts
|
||||||
// handles stmt block which returns something
|
// handles stmt block which returns something
|
||||||
// e.g. { return none }
|
// e.g. { return none }
|
||||||
if stmts.len > 0 && stmts.last() is ast.ExprStmt
|
if stmts.len > 0 && stmts.last() is ast.ExprStmt && stmts.last().typ != ast.void_type {
|
||||||
&& (stmts.last() as ast.ExprStmt).typ != ast.void_type {
|
|
||||||
g.gen_or_block_stmts(var_expr.str(), '', stmts, ret_typ, false)
|
g.gen_or_block_stmts(var_expr.str(), '', stmts, ret_typ, false)
|
||||||
} else {
|
} else {
|
||||||
// handles stmt block which doesn't returns value
|
// 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)
|
var_type = val_type.clear_flag(.option)
|
||||||
left.obj.typ = var_type
|
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)
|
key_str := g.get_comptime_selector_key_type(val.expr as ast.ComptimeSelector)
|
||||||
if key_str != '' {
|
if key_str != '' {
|
||||||
var_type = g.comptime_var_type_map[key_str] or { var_type }
|
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
|
left.obj.typ = var_type
|
||||||
}
|
}
|
||||||
} else if val is ast.IndexExpr {
|
} else if val is ast.IndexExpr {
|
||||||
if val.left is ast.Ident && g.is_generic_param_var((val as ast.IndexExpr).left) {
|
if val.left is ast.Ident && g.is_generic_param_var(val.left) {
|
||||||
ctyp := g.unwrap_generic(g.get_gn_var_type((val as ast.IndexExpr).left as ast.Ident))
|
ctyp := g.unwrap_generic(g.get_gn_var_type(val.left as ast.Ident))
|
||||||
if ctyp != ast.void_type {
|
if ctyp != ast.void_type {
|
||||||
var_type = ctyp
|
var_type = ctyp
|
||||||
val_type = var_type
|
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)
|
unaliased_right_sym := g.table.final_sym(unwrapped_val_type)
|
||||||
is_fixed_array_var := unaliased_right_sym.kind == .array_fixed && val !is ast.ArrayInit
|
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 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.CastExpr && val.expr !is ast.ArrayInit)
|
||||||
|| (val is ast.PrefixExpr && (val as ast.PrefixExpr).op == .arrow)
|
|| (val is ast.PrefixExpr && val.op == .arrow)
|
||||||
|| (val is ast.UnsafeExpr && (val as ast.UnsafeExpr).expr is ast.Ident))
|
|| (val is ast.UnsafeExpr && val.expr is ast.Ident)) && !g.pref.translated
|
||||||
&& !g.pref.translated
|
|
||||||
g.is_assign_lhs = true
|
g.is_assign_lhs = true
|
||||||
g.assign_op = node.op
|
g.assign_op = node.op
|
||||||
|
|
||||||
@ -572,7 +570,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
|||||||
}
|
}
|
||||||
if !is_used_var_styp {
|
if !is_used_var_styp {
|
||||||
if !val_type.has_flag(.option) && left_sym.info is ast.ArrayFixed
|
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..]} ')
|
g.write('${styp[3..]} ')
|
||||||
} else {
|
} else {
|
||||||
g.write('${styp} ')
|
g.write('${styp} ')
|
||||||
@ -668,7 +666,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
|||||||
g.write('{0}')
|
g.write('{0}')
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
is_option_auto_heap := is_auto_heap && is_option_unwrapped
|
||||||
if is_auto_heap {
|
if is_auto_heap {
|
||||||
g.write('HEAP(${styp}, (')
|
g.write('HEAP(${styp}, (')
|
||||||
@ -694,7 +692,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
|||||||
// var = &auto_heap_var
|
// var = &auto_heap_var
|
||||||
old_is_auto_heap := g.is_option_auto_heap
|
old_is_auto_heap := g.is_option_auto_heap
|
||||||
g.is_option_auto_heap = val_type.has_flag(.option) && val is ast.PrefixExpr
|
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()
|
&& ((val as ast.PrefixExpr).right as ast.Ident).is_auto_heap()
|
||||||
defer {
|
defer {
|
||||||
g.is_option_auto_heap = old_is_auto_heap
|
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}'
|
mr_var_name := 'mr_${node.pos.pos}'
|
||||||
mut is_option := return_type.has_flag(.option)
|
mut is_option := return_type.has_flag(.option)
|
||||||
mut mr_styp := g.typ(return_type.clear_flag(.result))
|
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
|
is_option = false
|
||||||
mr_styp = g.typ(return_type.clear_flags(.option, .result))
|
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 {
|
} else if node.op == .question {
|
||||||
cur_line := g.go_before_stmt(0).trim_space()
|
cur_line := g.go_before_stmt(0).trim_space()
|
||||||
mut expr_str := ''
|
mut expr_str := ''
|
||||||
if mut node.expr is ast.ComptimeSelector
|
if mut node.expr is ast.ComptimeSelector && node.expr.left is ast.Ident {
|
||||||
&& (node.expr as ast.ComptimeSelector).left is ast.Ident {
|
|
||||||
// val.$(field.name)?
|
// val.$(field.name)?
|
||||||
expr_str = '${node.expr.left.str()}.${g.comptime_for_field_value.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) {
|
} 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
|
// var?.field_opt
|
||||||
field_is_opt := (node.expr is ast.Ident && node.expr.is_auto_heap()
|
field_is_opt := node.expr is ast.Ident && node.expr.is_auto_heap()
|
||||||
&& node.expr.or_expr.kind != .absent && field_typ.has_flag(.option))
|
&& node.expr.or_expr.kind != .absent && field_typ.has_flag(.option)
|
||||||
if field_is_opt {
|
if field_is_opt {
|
||||||
g.write('((${g.base_type(field_typ)})')
|
g.write('((${g.base_type(field_typ)})')
|
||||||
}
|
}
|
||||||
@ -4194,14 +4193,14 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
|
|||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut g Gen) is_generic_param_var(node ast.Expr) bool {
|
pub fn (mut g Gen) is_generic_param_var(node ast.Expr) bool {
|
||||||
return node is ast.Ident && node.info is ast.IdentVar
|
return node is ast.Ident && node.info is ast.IdentVar && node.obj is ast.Var
|
||||||
&& (node as ast.Ident).obj is ast.Var && ((node as ast.Ident).obj as ast.Var).ct_type_var == .generic_param
|
&& ((node as ast.Ident).obj as ast.Var).ct_type_var == .generic_param
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut g Gen) is_comptime_var(node ast.Expr) bool {
|
pub fn (mut g Gen) is_comptime_var(node ast.Expr) bool {
|
||||||
return node is ast.Ident && node.info is ast.IdentVar
|
return node is ast.Ident && node.info is ast.IdentVar && node.obj is ast.Var
|
||||||
&& (node as ast.Ident).obj is ast.Var && ((node as ast.Ident).obj as ast.Var).ct_type_var != .no_comptime
|
&& ((node as ast.Ident).obj as ast.Var).ct_type_var != .no_comptime
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) ident(node ast.Ident) {
|
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 {
|
if node.exprs.len > 0 {
|
||||||
// skip `return $vweb.html()`
|
// 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.inside_return_tmpl = true
|
||||||
g.expr(node.exprs[0])
|
g.expr(node.exprs[0])
|
||||||
g.inside_return_tmpl = false
|
g.inside_return_tmpl = false
|
||||||
@ -5487,7 +5486,7 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) {
|
|||||||
if g.pref.translated {
|
if g.pref.translated {
|
||||||
def_builder.write_string(' = ${g.expr_string(field.expr)}')
|
def_builder.write_string(' = ${g.expr_string(field.expr)}')
|
||||||
} else if (field.expr.is_literal() && should_init) || cinit
|
} 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) {
|
|| (is_simple_unsafe_expr && should_init) {
|
||||||
// Simple literals can be initialized right away in global scope in C.
|
// Simple literals can be initialized right away in global scope in C.
|
||||||
// e.g. `int myglobal = 10;`
|
// 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
|
g.inside_or_block = false
|
||||||
}
|
}
|
||||||
stmts := or_block.stmts
|
stmts := or_block.stmts
|
||||||
if stmts.len > 0 && stmts.last() is ast.ExprStmt
|
if stmts.len > 0 && stmts.last() is ast.ExprStmt && stmts.last().typ != ast.void_type {
|
||||||
&& (stmts.last() as ast.ExprStmt).typ != ast.void_type {
|
|
||||||
g.gen_or_block_stmts(cvar_name, mr_styp, stmts, return_type, true)
|
g.gen_or_block_stmts(cvar_name, mr_styp, stmts, return_type, true)
|
||||||
} else {
|
} else {
|
||||||
g.stmts(stmts)
|
g.stmts(stmts)
|
||||||
|
@ -749,7 +749,7 @@ fn (mut g Gen) pop_existing_comptime_values() {
|
|||||||
[inline]
|
[inline]
|
||||||
fn (mut g Gen) is_comptime_selector_field_name(node ast.SelectorExpr, field_name string) bool {
|
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
|
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
|
// 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 != '' {
|
if key_str != '' {
|
||||||
return g.comptime_var_type_map[key_str] or { ast.void_type }
|
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
|
// field_var.typ from $for field
|
||||||
return g.comptime_for_field_type
|
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)
|
g.gen_plain_infix_expr(node)
|
||||||
} else if (left.typ.idx() == ast.string_type_idx || (!has_defined_eq_operator
|
} 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
|
&& 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
|
// `str == ''` -> `str.len == 0` optimization
|
||||||
g.write('(')
|
g.write('(')
|
||||||
g.expr(node.left)
|
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
|
mut covered_enum_cap := 0
|
||||||
if cond_fsym.info is ast.Enum {
|
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
|
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 {
|
for branch in node.branches {
|
||||||
if branch.is_else {
|
if branch.is_else {
|
||||||
if cond_fsym.info is ast.Enum {
|
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 {
|
if val !in covered_enum {
|
||||||
g.writeln('case ${cname}${val}:')
|
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) {
|
pub fn (mut f Gen) assert_stmt(node ast.AssertStmt) {
|
||||||
f.write('assert ')
|
f.write('assert ')
|
||||||
mut expr := node.expr
|
mut expr := node.expr
|
||||||
for expr is ast.ParExpr {
|
for mut expr is ast.ParExpr {
|
||||||
expr = (expr as ast.ParExpr).expr
|
expr = expr.expr
|
||||||
}
|
}
|
||||||
f.expr(expr)
|
f.expr(expr)
|
||||||
f.writeln('')
|
f.writeln('')
|
||||||
|
@ -475,7 +475,7 @@ fn (mut p Parser) parse_type() ast.Type {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
sym := p.table.sym(typ)
|
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()))
|
p.error_with_pos('an inline sum type cannot be an Option', option_pos.extend(p.prev_tok.pos()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user