@@ -2165,7 +2165,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
21652165// applicable to situations where the expr_typ does not have `option` and `result`,
21662166// e.g. field default: "foo ?int = 1", field assign: "foo = 1", field init: "foo: 1"
21672167fn (mut g Gen) expr_with_tmp_var (expr ast.Expr, expr_typ ast.Type, ret_typ ast.Type, tmp_var string ) {
2168- if ! ret_typ.has_flag (.option) && ! ret_typ. has_flag (.result ) {
2168+ if ! ret_typ.has_option_or_result ( ) {
21692169 panic ('cgen: parameter `ret_typ` of function `expr_with_tmp_var()` must be an Option or Result' )
21702170 }
21712171
@@ -2182,6 +2182,8 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
21822182 g.writeln ('${g.styp(ret_typ)} ${tmp_var} = {.state=2, .err=${expr.name} };' )
21832183 } else {
21842184 mut simple_assign := false
2185+ expr_typ_is_option := expr_typ.has_flag (.option)
2186+ ret_typ_is_option := ret_typ.has_flag (.option)
21852187 if ret_typ.has_flag (.generic) {
21862188 if expr is ast.SelectorExpr && g.cur_concrete_types.len == 0 {
21872189 // resolve generic struct on selectorExpr inside non-generic function
@@ -2203,8 +2205,8 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
22032205 } else {
22042206 g.writeln ('${g.styp(ret_typ)} ${tmp_var} ;' )
22052207 }
2206- if ret_typ. has_flag (.option) {
2207- if expr_typ. has_flag (.option) && expr in [ast.StructInit, ast.ArrayInit, ast.MapInit] {
2208+ if ret_typ_is_option {
2209+ if expr_typ_is_option && expr in [ast.StructInit, ast.ArrayInit, ast.MapInit] {
22082210 simple_assign = expr is ast.StructInit
22092211 if simple_assign {
22102212 g.write ('${tmp_var} = ' )
@@ -2214,13 +2216,13 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
22142216 } else {
22152217 simple_assign =
22162218 ((expr is ast.SelectorExpr || (expr is ast.Ident && ! expr.is_auto_heap ()))
2217- && ret_typ.is_ptr () && expr_typ.is_ptr () && expr_typ. has_flag (.option) )
2219+ && ret_typ.is_ptr () && expr_typ.is_ptr () && expr_typ_is_option )
22182220 || (expr_typ == ret_typ && ! (expr_typ.has_option_or_result ()
22192221 && (expr_typ.is_ptr () || expr is ast.LambdaExpr )))
22202222 // option ptr assignment simplification
22212223 if simple_assign {
22222224 g.write ('${tmp_var} = ' )
2223- } else if expr_typ. has_flag (.option) && expr is ast.PrefixExpr
2225+ } else if expr_typ_is_option && expr is ast.PrefixExpr
22242226 && expr.right is ast.StructInit
22252227 && (expr.right as ast.StructInit ).init_fields.len == 0 {
22262228 g.write ('_option_none(&(${styp} []) { ' )
@@ -2243,7 +2245,7 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
22432245 g.write ('_result_ok(&(${styp} []) { ' )
22442246 }
22452247 g.expr_with_cast (expr, expr_typ, ret_typ)
2246- if ret_typ. has_flag (.option) {
2248+ if ret_typ_is_option {
22472249 if simple_assign {
22482250 g.writeln (';' )
22492251 } else {
@@ -2448,8 +2450,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
24482450 if method.return_type.has_flag (.option) {
24492451 // Register an option if it's not registered yet
24502452 g.register_option (method.return_type)
2451- }
2452- if method.return_type.has_flag (.result) {
2453+ } else if method.return_type.has_flag (.result) {
24532454 // Register a result if it's not registered yet
24542455 g.register_result (method.return_type)
24552456 }
@@ -2896,7 +2897,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
28962897 neither_void := ast.voidptr_type ! in [got_type, expected_type]
28972898 && ast.nil_type ! in [got_type, expected_type]
28982899 if expected_type.has_flag (.shared_f) && ! got_type_raw.has_flag (.shared_f)
2899- && ! expected_type.has_flag (.option) && ! expected_type. has_flag (.result ) {
2900+ && ! expected_type.has_option_or_result ( ) {
29002901 shared_styp := exp_styp[0 ..exp_styp.len - 1 ] // `shared` implies ptr, so eat one `*`
29012902 if got_type_raw.is_ptr () {
29022903 g.error ('cannot convert reference to `shared`' , expr.pos ())
@@ -2939,8 +2940,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
29392940 return
29402941 }
29412942 }
2942- if exp_sym.kind == .function && ! expected_type.has_flag (.option)
2943- && ! expected_type.has_flag (.result) {
2943+ if exp_sym.kind == .function && ! expected_type.has_option_or_result () {
29442944 g.write ('(voidptr)' )
29452945 }
29462946 // no cast
@@ -3626,7 +3626,8 @@ fn (mut g Gen) expr(node_ ast.Expr) {
36263626 node.return_type.clear_option_and_result ()
36273627 }
36283628 mut shared_styp := ''
3629- if g.is_shared && ! ret_type.has_flag (.shared_f) && ! g.inside_or_block {
3629+ ret_typ_is_shared := ret_type.has_flag (.shared_f)
3630+ if g.is_shared && ! ret_typ_is_shared && ! g.inside_or_block {
36303631 ret_sym := g.table.sym (ret_type)
36313632 shared_typ := if ret_type.is_ptr () {
36323633 ret_type.deref ().set_flag (.shared_f)
@@ -3648,8 +3649,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
36483649 0
36493650 }
36503651
3651- if g.is_shared && ! ret_type.has_flag (.shared_f) && ! g.inside_or_block
3652- && ret_type.is_ptr () {
3652+ if g.is_shared && ! ret_typ_is_shared && ! g.inside_or_block && ret_type.is_ptr () {
36533653 g.write ('*' .repeat (ret_type.nr_muls ()))
36543654 }
36553655 g.call_expr (node)
@@ -3665,7 +3665,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
36653665 }
36663666 g.strs_to_free0 = []
36673667 }
3668- if g.is_shared && ! ret_type. has_flag (.shared_f) && ! g.inside_or_block {
3668+ if g.is_shared && ! ret_typ_is_shared && ! g.inside_or_block {
36693669 g.writeln ('}, sizeof(${shared_styp} ))' )
36703670 }
36713671 /*
@@ -4524,10 +4524,10 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
45244524 cast_sym := g.table.sym (var_typ)
45254525
45264526 mut param_var := strings.new_builder (50 )
4527+ is_option := obj.typ.has_flag (.option)
4528+ var_typ_is_option := var_typ.has_flag (.option)
45274529 if obj.smartcasts.len > 0 {
4528- is_option_unwrap := obj.typ.has_flag (.option)
4529- && var_typ == obj.typ.clear_flag (.option)
4530- is_option := obj.typ.has_flag (.option)
4530+ is_option_unwrap := is_option && var_typ == obj.typ.clear_flag (.option)
45314531 mut opt_cast := false
45324532 mut func := if cast_sym.info is ast.Aggregate {
45334533 ''
@@ -4571,7 +4571,7 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
45714571 param_var.write_string ('.data)' )
45724572 }
45734573 param_var.write_string ('${dot} _${cast_sym.cname} ' )
4574- } else if obj.typ. has_flag (.option) && ! var_typ. has_flag (.option) {
4574+ } else if is_option && ! var_typ_is_option {
45754575 param_var.write_string ('${obj.name} .data' )
45764576 } else {
45774577 param_var.write_string ('${obj.name} ' )
@@ -4581,15 +4581,15 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
45814581 values.write_string ('${func} (${param_var.str()} )}' )
45824582 } else {
45834583 func := g.get_str_fn (var_typ)
4584- if obj.typ. has_flag (.option) && ! var_typ. has_flag (.option) {
4584+ if is_option && ! var_typ_is_option {
45854585 // option unwrap
45864586 base_typ := g.base_type (obj.typ)
45874587 values.write_string ('${func} (*(${base_typ} *)${obj.name} .data)}' )
45884588 } else {
45894589 _ , str_method_expects_ptr , _ := cast_sym.str_method_info ()
45904590
45914591 // eprintln(">> ${obj.name} | str expects ptr? ${str_method_expects_ptr} | ptr? ${var_typ.is_ptr()} || auto heap? ${obj.is_auto_heap} | auto deref? ${obj.is_auto_deref}")
4592- deref := if var_typ. has_flag (.option) {
4592+ deref := if var_typ_is_option {
45934593 ''
45944594 } else if str_method_expects_ptr && ! obj.typ.is_ptr () {
45954595 '&'
@@ -5355,26 +5355,27 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
53555355 if g.comptime.is_comptime_expr (node.expr) {
53565356 expr_type = g.unwrap_generic (g.comptime.get_type (node.expr))
53575357 }
5358+ node_typ_is_option := node.typ.has_flag (.option)
53585359 if sym.kind in [.sum_type, .interface ] {
5359- if node.typ. has_flag (.option) && node.expr is ast.None {
5360+ if node_typ_is_option && node.expr is ast.None {
53605361 g.gen_option_error (node.typ, node.expr)
53615362 } else if node.expr is ast.Ident && g.comptime.is_comptime_variant_var (node.expr) {
53625363 g.expr_with_cast (node.expr, g.comptime.type_map['${g.comptime.comptime_for_variant_var} .typ' ],
53635364 node_typ)
5364- } else if node.typ. has_flag (.option) {
5365+ } else if node_typ_is_option {
53655366 g.expr_with_opt (node.expr, expr_type, node.typ)
53665367 } else {
53675368 g.expr_with_cast (node.expr, expr_type, node_typ)
53685369 }
5369- } else if ! node.typ. has_flag (.option) && ! node.typ.is_ptr () && sym.info is ast.Struct
5370+ } else if ! node_typ_is_option && ! node.typ.is_ptr () && sym.info is ast.Struct
53705371 && ! sym.info.is_typedef {
53715372 // deprecated, replaced by Struct{...exr}
53725373 styp := g.styp (node.typ)
53735374 g.write ('*((${styp} *)(&' )
53745375 g.expr (node.expr)
53755376 g.write ('))' )
53765377 } else if sym.kind == .alias && g.table.final_sym (node.typ).kind == .array_fixed {
5377- if node.typ. has_flag (.option) {
5378+ if node_typ_is_option {
53785379 g.expr_with_opt (node.expr, expr_type, node.typ)
53795380 } else {
53805381 if node.expr is ast.ArrayInit && g.assign_op != .decl_assign {
@@ -5409,9 +5410,9 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
54095410 cast_label = '(${styp} )'
54105411 }
54115412 }
5412- if node.typ. has_flag (.option) && node.expr is ast.None {
5413+ if node_typ_is_option && node.expr is ast.None {
54135414 g.gen_option_error (node.typ, node.expr)
5414- } else if node.typ. has_flag (.option) {
5415+ } else if node_typ_is_option {
54155416 if sym.info is ast.Alias {
54165417 if sym.info.parent_type.has_flag (.option) {
54175418 cur_stmt := g.go_before_last_stmt ()
@@ -6893,13 +6894,13 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
68936894 } else {
68946895 mut is_array_fixed := false
68956896 mut return_wrapped := false
6897+ mut return_is_option := is_option && return_type.has_option_or_result ()
68966898 if is_option {
68976899 is_array_fixed = g.table.final_sym (return_type).kind == .array_fixed
68986900 if ! is_array_fixed {
68996901 if g.inside_return && ! g.inside_struct_init
69006902 && expr_stmt.expr is ast.CallExpr && (expr_stmt.expr as ast.CallExpr ).return_type.has_option_or_result ()
6901- && g.cur_fn.return_type.has_option_or_result ()
6902- && return_type.has_option_or_result ()
6903+ && g.cur_fn.return_type.has_option_or_result () && return_is_option
69036904 && expr_stmt.expr.or_block.kind == .absent {
69046905 g.write ('${cvar_name} = ' )
69056906 return_wrapped = true
@@ -6919,7 +6920,7 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
69196920 }
69206921 // return expr or { fn_returns_option() }
69216922 if is_option && g.inside_return && expr_stmt.expr is ast.CallExpr
6922- && return_type. has_option_or_result () {
6923+ && return_is_option {
69236924 g.expr_with_cast (expr_stmt.expr, expr_stmt.typ, return_type)
69246925 } else {
69256926 old_inside_opt_data := g.inside_opt_data
0 commit comments