1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

v: use autocasting in if conditions inside the compiler (#18708)

This commit is contained in:
yuyi 2023-06-30 00:37:36 +08:00 committed by GitHub
parent 85160923b6
commit f122703a43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 52 additions and 56 deletions

View File

@ -247,8 +247,8 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
// c.error('cannot assign a `none` value to a non-option variable', right.pos())
// }
}
if mut left is ast.Ident
&& (left as ast.Ident).info is ast.IdentVar && right is ast.Ident && (right as ast.Ident).name in c.global_names {
if mut left is ast.Ident && left.info is ast.IdentVar && right is ast.Ident
&& right.name in c.global_names {
ident_var_info := left.info as ast.IdentVar
if ident_var_info.share == .shared_t {
c.error('cannot assign global variable to shared variable', right.pos())
@ -345,17 +345,17 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
left.obj.ct_type_var = .field_var
left.obj.typ = c.comptime_fields_default_type
}
} else if right is ast.Ident
&& (right as ast.Ident).obj is ast.Var && (right as ast.Ident).or_expr.kind == .absent {
if ((right as ast.Ident).obj as ast.Var).ct_type_var != .no_comptime {
} else if mut right is ast.Ident && right.obj is ast.Var
&& (right as ast.Ident).or_expr.kind == .absent {
if (right.obj as ast.Var).ct_type_var != .no_comptime {
ctyp := c.get_comptime_var_type(right)
if ctyp != ast.void_type {
left.obj.ct_type_var = ((right as ast.Ident).obj as ast.Var).ct_type_var
left.obj.ct_type_var = (right.obj as ast.Var).ct_type_var
left.obj.typ = ctyp
}
}
} else if right is ast.DumpExpr
&& (right as ast.DumpExpr).expr is ast.ComptimeSelector {
&& right.expr is ast.ComptimeSelector {
left.obj.ct_type_var = .field_var
left.obj.typ = c.comptime_fields_default_type
}

View File

@ -1044,7 +1044,7 @@ fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
} else if arg_sym.kind == .any && c.table.cur_fn.generic_names.len > 0
&& c.table.cur_fn.params.len > 0 && func.generic_names.len > 0
&& arg.expr is ast.Ident && arg_i !in arg_inferred {
var_name := (arg.expr as ast.Ident).name
var_name := arg.expr.name
for k, cur_param in c.table.cur_fn.params {
if !cur_param.typ.has_flag(.generic) || k < gi || cur_param.name != var_name {
continue

View File

@ -1372,7 +1372,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
return node.expr_type
}
node.expr_type = typ
if !(node.expr is ast.Ident && (node.expr as ast.Ident).kind == .constant) {
if !(node.expr is ast.Ident && node.expr.kind == .constant) {
if node.expr_type.has_flag(.option) {
c.error('cannot access fields of an Option, handle the error with `or {...}` or propagate it with `?`',
node.pos)
@ -3821,8 +3821,8 @@ fn (c &Checker) has_return(stmts []ast.Stmt) ?bool {
[inline]
pub fn (mut c Checker) is_comptime_var(node ast.Expr) bool {
return node is ast.Ident
&& (node as ast.Ident).info is ast.IdentVar && (node as ast.Ident).kind == .variable && ((node as ast.Ident).obj as ast.Var).ct_type_var != .no_comptime
return node is ast.Ident && node.info is ast.IdentVar
&& (node as ast.Ident).kind == .variable && ((node as ast.Ident).obj as ast.Var).ct_type_var != .no_comptime
}
fn (mut c Checker) mark_as_referenced(mut node ast.Expr, as_interface bool) {
@ -4121,7 +4121,7 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
typ = (typ_sym.info as ast.Aggregate).types[0]
}
if typ.has_flag(.option) {
if node.left is ast.Ident && (node.left as ast.Ident).or_expr.kind == .absent {
if node.left is ast.Ident && node.left.or_expr.kind == .absent {
c.error('type `?${typ_sym.name}` is an Option, it must be unwrapped first; use `var?[]` to do it',
node.left.pos())
} else if node.left is ast.CallExpr {

View File

@ -11,7 +11,7 @@ import v.pkgconfig
[inline]
fn (mut c Checker) get_ct_type_var(node ast.Expr) ast.ComptimeVarKind {
return if node is ast.Ident && (node as ast.Ident).obj is ast.Var {
return if node is ast.Ident && node.obj is ast.Var {
(node.obj as ast.Var).ct_type_var
} else {
.no_comptime
@ -20,7 +20,7 @@ fn (mut c Checker) get_ct_type_var(node ast.Expr) ast.ComptimeVarKind {
[inline]
fn (mut c Checker) get_comptime_var_type(node ast.Expr) ast.Type {
if node is ast.Ident && (node as ast.Ident).obj is ast.Var {
if node is ast.Ident && node.obj is ast.Var {
return match (node.obj as ast.Var).ct_type_var {
.generic_param {
// generic parameter from current function
@ -917,14 +917,14 @@ fn (mut c Checker) get_comptime_selector_type(node ast.ComptimeSelector, default
[inline]
fn (mut c Checker) is_comptime_selector_field_name(node ast.SelectorExpr, field_name string) bool {
return c.inside_comptime_for_field && node.expr is ast.Ident
&& (node.expr as ast.Ident).name == c.comptime_for_field_var && node.field_name == field_name
&& node.expr.name == c.comptime_for_field_var && node.field_name == field_name
}
// is_comptime_selector_type checks if the SelectorExpr is related to $for variable accessing .typ field
[inline]
fn (mut c Checker) is_comptime_selector_type(node ast.SelectorExpr) bool {
if c.inside_comptime_for_field && node.expr is ast.Ident {
return (node.expr as ast.Ident).name == c.comptime_for_field_var && node.field_name == 'typ'
return node.expr.name == c.comptime_for_field_var && node.field_name == 'typ'
}
return false
}
@ -933,7 +933,7 @@ fn (mut c Checker) is_comptime_selector_type(node ast.SelectorExpr) bool {
[inline]
fn (mut c Checker) check_comptime_is_field_selector(node ast.SelectorExpr) bool {
if c.inside_comptime_for_field && node.expr is ast.Ident {
return (node.expr as ast.Ident).name == c.comptime_for_field_var
return node.expr.name == c.comptime_for_field_var
}
return false
}

View File

@ -117,7 +117,7 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
} else {
.skip
}
} else if left is ast.Ident && (left as ast.Ident).info is ast.IdentVar {
} else if left is ast.Ident && left.info is ast.IdentVar {
is_comptime_type_is_expr = true
if var := left.scope.find_var(left.name) {
checked_type = c.unwrap_generic(var.typ)
@ -497,9 +497,8 @@ fn (mut c Checker) smartcast_if_conds(node ast.Expr, mut scope ast.Scope) {
true
}
if is_variable {
if (node.left is ast.Ident && (node.left as ast.Ident).is_mut)
|| (node.left is ast.SelectorExpr
&& (node.left as ast.SelectorExpr).is_mut) {
if (node.left is ast.Ident && node.left.is_mut)
|| (node.left is ast.SelectorExpr && node.left.is_mut) {
c.fail_if_immutable(node.left)
}
// TODO: Add check for sum types in a way that it doesn't break a lot of compiler code

View File

@ -500,7 +500,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
c.error('array append cannot be used in an expression', node.pos)
}
if left_type.has_flag(.option) && node.left is ast.Ident
&& (node.left as ast.Ident).or_expr.kind == .absent {
&& node.left.or_expr.kind == .absent {
c.error('unwrapped Option cannot be used in an infix expression',
node.pos)
}

View File

@ -22,8 +22,8 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
// we setting this here rather than at the end of the method
// since it is used in c.match_exprs() it saves checking twice
node.cond_type = ast.mktyp(cond_type)
if (node.cond is ast.Ident && (node.cond as ast.Ident).is_mut)
|| (node.cond is ast.SelectorExpr && (node.cond as ast.SelectorExpr).is_mut) {
if (node.cond is ast.Ident && node.cond.is_mut)
|| (node.cond is ast.SelectorExpr && node.cond.is_mut) {
c.fail_if_immutable(node.cond)
}
c.ensure_type_exists(node.cond_type, node.pos) or { return ast.void_type }

View File

@ -157,7 +157,7 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
}
for i, exp_type in expected_types {
exprv := node.exprs[expr_idxs[i]]
if exprv is ast.Ident && (exprv as ast.Ident).or_expr.kind == .propagate_option {
if exprv is ast.Ident && exprv.or_expr.kind == .propagate_option {
if exp_type.has_flag(.option) {
c.warn('unwrapping option is redundant as the function returns option',
node.pos)

View File

@ -231,7 +231,7 @@ pub fn (mut e Eval) register_symbol(stmt ast.Stmt, mod string, file string) {
cond := branch.cond
match cond {
ast.Ident {
match (branch.cond as ast.Ident).name {
match cond.name {
'windows' {
do_if = e.pref.os == .windows
}

View File

@ -8,7 +8,7 @@ import v.util
import v.token
fn (mut g Gen) expr_with_opt_or_block(expr ast.Expr, expr_typ ast.Type, var_expr ast.Expr, ret_typ ast.Type, in_heap bool) {
gen_or := expr is ast.Ident && (expr as ast.Ident).or_expr.kind != .absent
gen_or := expr is ast.Ident && expr.or_expr.kind != .absent
if gen_or {
old_inside_opt_or_res := g.inside_opt_or_res
g.inside_opt_or_res = true
@ -17,13 +17,13 @@ fn (mut g Gen) expr_with_opt_or_block(expr ast.Expr, expr_typ ast.Type, var_expr
g.write('))')
}
g.writeln(';')
expr_var := if expr is ast.Ident && (expr as ast.Ident).is_auto_heap() {
expr_var := if expr is ast.Ident && expr.is_auto_heap() {
'(*${expr.name})'
} else {
'${expr}'
}
g.writeln('if (${expr_var}.state != 0) { // assign')
if expr is ast.Ident && (expr as ast.Ident).or_expr.kind == .propagate_option {
if expr is ast.Ident && expr.or_expr.kind == .propagate_option {
g.writeln('\tpanic_option_not_set(_SLIT("none"));')
} else {
g.inside_or_block = true
@ -258,7 +258,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
key_str := '${val.method_name}.return_type'
var_type = g.comptime_var_type_map[key_str] or { var_type }
left.obj.typ = var_type
} else if is_decl && val is ast.Ident && (val as ast.Ident).info is ast.IdentVar {
} else if is_decl && val is ast.Ident && val.info is ast.IdentVar {
val_info := (val as ast.Ident).info
gen_or = val.or_expr.kind != .absent
if val_info.is_option && gen_or {
@ -668,8 +668,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
g.write('{0}')
}
} else {
is_option_unwrapped := (val is ast.Ident
&& (val as ast.Ident).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}, (')

View File

@ -1888,9 +1888,9 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
if ret_typ.has_flag(.generic) {
if expr is ast.SelectorExpr && g.cur_concrete_types.len == 0 {
// resolve generic struct on selectorExpr inside non-generic function
if expr.expr is ast.Ident && (expr.expr as ast.Ident).obj is ast.Var {
if ((expr.expr as ast.Ident).obj as ast.Var).expr is ast.StructInit {
g.cur_concrete_types << (g.table.sym((expr.expr as ast.Ident).obj.typ).info as ast.Struct).concrete_types
if expr.expr is ast.Ident && expr.expr.obj is ast.Var {
if (expr.expr.obj as ast.Var).expr is ast.StructInit {
g.cur_concrete_types << (g.table.sym(expr.expr.obj.typ).info as ast.Struct).concrete_types
}
}
}
@ -1908,8 +1908,8 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
g.write('_option_none(&(${styp}[]) { ')
}
} else {
is_ptr_to_ptr_assign = (expr is ast.SelectorExpr
|| (expr is ast.Ident && !(expr as ast.Ident).is_auto_heap()))
is_ptr_to_ptr_assign =
(expr is ast.SelectorExpr || (expr is ast.Ident && !expr.is_auto_heap()))
&& ret_typ.is_ptr() && expr_typ.is_ptr() && expr_typ.has_flag(.option)
// option ptr assignment simplification
if is_ptr_to_ptr_assign {
@ -2294,8 +2294,7 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp_is_ptr
}
g.write('${fname}(')
if !got_is_ptr && !got_is_fn {
if !expr.is_lvalue()
|| (expr is ast.Ident && (expr as ast.Ident).obj.is_simple_define_const()) {
if !expr.is_lvalue() || (expr is ast.Ident && expr.obj.is_simple_define_const()) {
// Note: the `_to_sumtype_` family of functions do call memdup internally, making
// another duplicate with the HEAP macro is redundant, so use ADDR instead:
promotion_macro_name := if fname.contains('_to_sumtype_') { 'ADDR' } else { 'HEAP' }
@ -3708,8 +3707,8 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
}
}
// var?.field_opt
field_is_opt := (node.expr is ast.Ident && (node.expr as ast.Ident).is_auto_heap()
&& (node.expr as ast.Ident).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)})')
}
@ -4183,14 +4182,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 as ast.Ident).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 as ast.Ident).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 as ast.Ident).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 as ast.Ident).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) {
@ -4535,8 +4534,7 @@ fn (mut g Gen) gen_result_error(target_type ast.Type, expr ast.Expr) {
fn (mut g Gen) gen_option_error(target_type ast.Type, expr ast.Expr) {
styp := g.typ(g.unwrap_generic(target_type))
g.write('(${styp}){ .state=2, .err=')
if target_type.has_flag(.option) && expr is ast.Ident
&& (expr as ast.Ident).or_expr.kind == .propagate_option {
if target_type.has_flag(.option) && expr is ast.Ident && expr.or_expr.kind == .propagate_option {
g.expr(ast.None{}) // option type unwrapping error
} else {
g.expr(expr)

View File

@ -695,7 +695,8 @@ fn (mut g Gen) comptime_if_cond(cond ast.Expr, pkg_exist bool) (bool, bool) {
}
ast.SelectorExpr {
if g.inside_comptime_for_field && cond.expr is ast.Ident
&& (cond.expr as ast.Ident).name == g.comptime_for_field_var && cond.field_name in ['is_mut', 'is_pub', 'is_shared', 'is_atomic', 'is_option', 'is_array', 'is_map', 'is_chan', 'is_struct', 'is_alias', 'is_enum'] {
&& cond.expr.name == g.comptime_for_field_var
&& cond.field_name in ['is_mut', 'is_pub', 'is_shared', 'is_atomic', 'is_option', 'is_array', 'is_map', 'is_chan', 'is_struct', 'is_alias', 'is_enum'] {
ret_bool := g.get_comptime_selector_bool_field(cond.field_name)
g.write(ret_bool.str())
return ret_bool, true
@ -758,13 +759,13 @@ fn (mut g Gen) is_comptime_selector_field_name(node ast.SelectorExpr, field_name
[inline]
fn (mut g Gen) is_comptime_selector_type(node ast.SelectorExpr) bool {
if g.inside_comptime_for_field && node.expr is ast.Ident {
return (node.expr as ast.Ident).name == g.comptime_for_field_var && node.field_name == 'typ'
return node.expr.name == g.comptime_for_field_var && node.field_name == 'typ'
}
return false
}
fn (mut g Gen) get_comptime_var_type(node ast.Expr) ast.Type {
if node is ast.Ident && (node as ast.Ident).obj is ast.Var {
if node is ast.Ident && node.obj is ast.Var {
return match (node.obj as ast.Var).ct_type_var {
.generic_param {
// generic parameter from current function

View File

@ -2155,7 +2155,7 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
&& g.table.unaliased_type(arg_typ).is_pointer() && expected_type.is_pointer()) {
if arg.is_mut {
if exp_sym.kind == .array {
if (arg.expr is ast.Ident && (arg.expr as ast.Ident).kind == .variable)
if (arg.expr is ast.Ident && arg.expr.kind == .variable)
|| arg.expr is ast.SelectorExpr {
g.write('&/*arr*/')
g.expr(arg.expr)

View File

@ -739,7 +739,7 @@ fn (mut g Gen) infix_expr_arithmetic_op(node ast.InfixExpr) {
}
mut right_var := ''
if node.right is ast.Ident && (node.right as ast.Ident).or_expr.kind != .absent {
if node.right is ast.Ident && node.right.or_expr.kind != .absent {
cur_line := g.go_before_stmt(0).trim_space()
right_var = g.new_tmp_var()
g.write('${g.typ(right.typ)} ${right_var} = ')

View File

@ -69,9 +69,8 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
}
if (node.cond in [ast.Ident, ast.IntegerLiteral, ast.StringLiteral, ast.FloatLiteral]
&& (node.cond !is ast.Ident || (node.cond is ast.Ident
&& (node.cond as ast.Ident).or_expr.kind == .absent)))
|| (node.cond is ast.SelectorExpr
&& (node.cond as ast.SelectorExpr).or_block.kind == .absent
&& node.cond.or_expr.kind == .absent))) || (node.cond is ast.SelectorExpr
&& node.cond.or_block.kind == .absent
&& ((node.cond as ast.SelectorExpr).expr !is ast.CallExpr
|| ((node.cond as ast.SelectorExpr).expr as ast.CallExpr).or_block.kind == .absent)) {
cond_var = g.expr_string(node.cond)

View File

@ -105,7 +105,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
}
} else if sym_has_str_method
|| sym.kind in [.array, .array_fixed, .map, .struct_, .multi_return, .sum_type, .interface_] {
unwrap_option := expr is ast.Ident && (expr as ast.Ident).or_expr.kind == .propagate_option
unwrap_option := expr is ast.Ident && expr.or_expr.kind == .propagate_option
exp_typ := if unwrap_option { typ.clear_flag(.option) } else { typ }
is_ptr := exp_typ.is_ptr()
is_var_mut := expr.is_auto_deref_var()