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()) // c.error('cannot assign a `none` value to a non-option variable', right.pos())
// } // }
} }
if mut left is ast.Ident if mut left is ast.Ident && left.info is ast.IdentVar && right is ast.Ident
&& (left as ast.Ident).info is ast.IdentVar && right is ast.Ident && (right as ast.Ident).name in c.global_names { && right.name in c.global_names {
ident_var_info := left.info as ast.IdentVar ident_var_info := left.info as ast.IdentVar
if ident_var_info.share == .shared_t { if ident_var_info.share == .shared_t {
c.error('cannot assign global variable to shared variable', right.pos()) 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.ct_type_var = .field_var
left.obj.typ = c.comptime_fields_default_type left.obj.typ = c.comptime_fields_default_type
} }
} else if right is ast.Ident } else if mut right is ast.Ident && right.obj is ast.Var
&& (right as ast.Ident).obj is ast.Var && (right as ast.Ident).or_expr.kind == .absent { && (right as ast.Ident).or_expr.kind == .absent {
if ((right as ast.Ident).obj as ast.Var).ct_type_var != .no_comptime { if (right.obj as ast.Var).ct_type_var != .no_comptime {
ctyp := c.get_comptime_var_type(right) ctyp := c.get_comptime_var_type(right)
if ctyp != ast.void_type { 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 left.obj.typ = ctyp
} }
} }
} else if right is ast.DumpExpr } 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.ct_type_var = .field_var
left.obj.typ = c.comptime_fields_default_type 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 } 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 && c.table.cur_fn.params.len > 0 && func.generic_names.len > 0
&& arg.expr is ast.Ident && arg_i !in arg_inferred { && 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 { for k, cur_param in c.table.cur_fn.params {
if !cur_param.typ.has_flag(.generic) || k < gi || cur_param.name != var_name { if !cur_param.typ.has_flag(.generic) || k < gi || cur_param.name != var_name {
continue continue

View File

@ -1372,7 +1372,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
return node.expr_type return node.expr_type
} }
node.expr_type = typ 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) { if node.expr_type.has_flag(.option) {
c.error('cannot access fields of an Option, handle the error with `or {...}` or propagate it with `?`', c.error('cannot access fields of an Option, handle the error with `or {...}` or propagate it with `?`',
node.pos) node.pos)
@ -3821,8 +3821,8 @@ fn (c &Checker) has_return(stmts []ast.Stmt) ?bool {
[inline] [inline]
pub fn (mut c Checker) is_comptime_var(node ast.Expr) bool { pub fn (mut c Checker) is_comptime_var(node ast.Expr) bool {
return node is ast.Ident return node is ast.Ident && node.info is ast.IdentVar
&& (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 && (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) { 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] typ = (typ_sym.info as ast.Aggregate).types[0]
} }
if typ.has_flag(.option) { 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', c.error('type `?${typ_sym.name}` is an Option, it must be unwrapped first; use `var?[]` to do it',
node.left.pos()) node.left.pos())
} else if node.left is ast.CallExpr { } else if node.left is ast.CallExpr {

View File

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

View File

@ -117,7 +117,7 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
} else { } else {
.skip .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 is_comptime_type_is_expr = true
if var := left.scope.find_var(left.name) { if var := left.scope.find_var(left.name) {
checked_type = c.unwrap_generic(var.typ) 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 true
} }
if is_variable { if is_variable {
if (node.left is ast.Ident && (node.left as ast.Ident).is_mut) if (node.left is ast.Ident && node.left.is_mut)
|| (node.left is ast.SelectorExpr || (node.left is ast.SelectorExpr && node.left.is_mut) {
&& (node.left as ast.SelectorExpr).is_mut) {
c.fail_if_immutable(node.left) 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 // 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) c.error('array append cannot be used in an expression', node.pos)
} }
if left_type.has_flag(.option) && node.left is ast.Ident 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', c.error('unwrapped Option cannot be used in an infix expression',
node.pos) 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 // we setting this here rather than at the end of the method
// since it is used in c.match_exprs() it saves checking twice // since it is used in c.match_exprs() it saves checking twice
node.cond_type = ast.mktyp(cond_type) node.cond_type = ast.mktyp(cond_type)
if (node.cond is ast.Ident && (node.cond as ast.Ident).is_mut) if (node.cond is ast.Ident && node.cond.is_mut)
|| (node.cond is ast.SelectorExpr && (node.cond as ast.SelectorExpr).is_mut) { || (node.cond is ast.SelectorExpr && node.cond.is_mut) {
c.fail_if_immutable(node.cond) c.fail_if_immutable(node.cond)
} }
c.ensure_type_exists(node.cond_type, node.pos) or { return ast.void_type } 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 { for i, exp_type in expected_types {
exprv := node.exprs[expr_idxs[i]] 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) { if exp_type.has_flag(.option) {
c.warn('unwrapping option is redundant as the function returns option', c.warn('unwrapping option is redundant as the function returns option',
node.pos) 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 cond := branch.cond
match cond { match cond {
ast.Ident { ast.Ident {
match (branch.cond as ast.Ident).name { match cond.name {
'windows' { 'windows' {
do_if = e.pref.os == .windows do_if = e.pref.os == .windows
} }

View File

@ -8,7 +8,7 @@ import v.util
import v.token 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) { 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 { if gen_or {
old_inside_opt_or_res := g.inside_opt_or_res old_inside_opt_or_res := g.inside_opt_or_res
g.inside_opt_or_res = true 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.write('))')
} }
g.writeln(';') 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})' '(*${expr.name})'
} else { } else {
'${expr}' '${expr}'
} }
g.writeln('if (${expr_var}.state != 0) { // assign') 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"));') g.writeln('\tpanic_option_not_set(_SLIT("none"));')
} else { } else {
g.inside_or_block = true 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' key_str := '${val.method_name}.return_type'
var_type = g.comptime_var_type_map[key_str] or { var_type } var_type = g.comptime_var_type_map[key_str] or { var_type }
left.obj.typ = 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 val_info := (val as ast.Ident).info
gen_or = val.or_expr.kind != .absent gen_or = val.or_expr.kind != .absent
if val_info.is_option && gen_or { if val_info.is_option && gen_or {
@ -668,8 +668,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 is_option_unwrapped := (val is ast.Ident && val.or_expr.kind != .absent)
&& (val as ast.Ident).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}, (')

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 ret_typ.has_flag(.generic) {
if expr is ast.SelectorExpr && g.cur_concrete_types.len == 0 { if expr is ast.SelectorExpr && g.cur_concrete_types.len == 0 {
// resolve generic struct on selectorExpr inside non-generic function // 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 is ast.Ident && expr.expr.obj is ast.Var {
if ((expr.expr as ast.Ident).obj as ast.Var).expr is ast.StructInit { if (expr.expr.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 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}[]) { ') g.write('_option_none(&(${styp}[]) { ')
} }
} else { } else {
is_ptr_to_ptr_assign = (expr is ast.SelectorExpr is_ptr_to_ptr_assign =
|| (expr is ast.Ident && !(expr as ast.Ident).is_auto_heap())) (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) && ret_typ.is_ptr() && expr_typ.is_ptr() && expr_typ.has_flag(.option)
// option ptr assignment simplification // option ptr assignment simplification
if is_ptr_to_ptr_assign { 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}(') g.write('${fname}(')
if !got_is_ptr && !got_is_fn { if !got_is_ptr && !got_is_fn {
if !expr.is_lvalue() if !expr.is_lvalue() || (expr is ast.Ident && expr.obj.is_simple_define_const()) {
|| (expr is ast.Ident && (expr as ast.Ident).obj.is_simple_define_const()) {
// Note: the `_to_sumtype_` family of functions do call memdup internally, making // Note: the `_to_sumtype_` family of functions do call memdup internally, making
// another duplicate with the HEAP macro is redundant, so use ADDR instead: // another duplicate with the HEAP macro is redundant, so use ADDR instead:
promotion_macro_name := if fname.contains('_to_sumtype_') { 'ADDR' } else { 'HEAP' } 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 // var?.field_opt
field_is_opt := (node.expr is ast.Ident && (node.expr as ast.Ident).is_auto_heap() field_is_opt := (node.expr is ast.Ident && node.expr.is_auto_heap()
&& (node.expr as ast.Ident).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)})')
} }
@ -4183,14 +4182,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 return node is ast.Ident && node.info is ast.IdentVar
&& (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 && (node as ast.Ident).obj is ast.Var && ((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 return node is ast.Ident && node.info is ast.IdentVar
&& (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 && (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) { 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) { fn (mut g Gen) gen_option_error(target_type ast.Type, expr ast.Expr) {
styp := g.typ(g.unwrap_generic(target_type)) styp := g.typ(g.unwrap_generic(target_type))
g.write('(${styp}){ .state=2, .err=') g.write('(${styp}){ .state=2, .err=')
if target_type.has_flag(.option) && expr is ast.Ident if target_type.has_flag(.option) && expr is ast.Ident && expr.or_expr.kind == .propagate_option {
&& (expr as ast.Ident).or_expr.kind == .propagate_option {
g.expr(ast.None{}) // option type unwrapping error g.expr(ast.None{}) // option type unwrapping error
} else { } else {
g.expr(expr) 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 { ast.SelectorExpr {
if g.inside_comptime_for_field && cond.expr is ast.Ident 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) ret_bool := g.get_comptime_selector_bool_field(cond.field_name)
g.write(ret_bool.str()) g.write(ret_bool.str())
return ret_bool, true return ret_bool, true
@ -758,13 +759,13 @@ fn (mut g Gen) is_comptime_selector_field_name(node ast.SelectorExpr, field_name
[inline] [inline]
fn (mut g Gen) is_comptime_selector_type(node ast.SelectorExpr) bool { fn (mut g Gen) is_comptime_selector_type(node ast.SelectorExpr) bool {
if g.inside_comptime_for_field && node.expr is ast.Ident { 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 return false
} }
fn (mut g Gen) get_comptime_var_type(node ast.Expr) ast.Type { 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 { return match (node.obj as ast.Var).ct_type_var {
.generic_param { .generic_param {
// generic parameter from current function // 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()) { && g.table.unaliased_type(arg_typ).is_pointer() && expected_type.is_pointer()) {
if arg.is_mut { if arg.is_mut {
if exp_sym.kind == .array { 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 { || arg.expr is ast.SelectorExpr {
g.write('&/*arr*/') g.write('&/*arr*/')
g.expr(arg.expr) g.expr(arg.expr)

View File

@ -739,7 +739,7 @@ fn (mut g Gen) infix_expr_arithmetic_op(node ast.InfixExpr) {
} }
mut right_var := '' 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() cur_line := g.go_before_stmt(0).trim_space()
right_var = g.new_tmp_var() right_var = g.new_tmp_var()
g.write('${g.typ(right.typ)} ${right_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] if (node.cond in [ast.Ident, ast.IntegerLiteral, ast.StringLiteral, ast.FloatLiteral]
&& (node.cond !is ast.Ident || (node.cond is ast.Ident && (node.cond !is ast.Ident || (node.cond is ast.Ident
&& (node.cond as ast.Ident).or_expr.kind == .absent))) && node.cond.or_expr.kind == .absent))) || (node.cond is ast.SelectorExpr
|| (node.cond is ast.SelectorExpr && node.cond.or_block.kind == .absent
&& (node.cond as ast.SelectorExpr).or_block.kind == .absent
&& ((node.cond as ast.SelectorExpr).expr !is ast.CallExpr && ((node.cond as ast.SelectorExpr).expr !is ast.CallExpr
|| ((node.cond as ast.SelectorExpr).expr as ast.CallExpr).or_block.kind == .absent)) { || ((node.cond as ast.SelectorExpr).expr as ast.CallExpr).or_block.kind == .absent)) {
cond_var = g.expr_string(node.cond) 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 } else if sym_has_str_method
|| sym.kind in [.array, .array_fixed, .map, .struct_, .multi_return, .sum_type, .interface_] { || 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 } exp_typ := if unwrap_option { typ.clear_flag(.option) } else { typ }
is_ptr := exp_typ.is_ptr() is_ptr := exp_typ.is_ptr()
is_var_mut := expr.is_auto_deref_var() is_var_mut := expr.is_auto_deref_var()