@@ -2165,7 +2165,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
2165
2165
// applicable to situations where the expr_typ does not have `option` and `result`,
2166
2166
// e.g. field default: "foo ?int = 1", field assign: "foo = 1", field init: "foo: 1"
2167
2167
fn (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 ( ) {
2169
2169
panic ('cgen: parameter `ret_typ` of function `expr_with_tmp_var()` must be an Option or Result' )
2170
2170
}
2171
2171
@@ -2182,6 +2182,8 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
2182
2182
g.writeln ('${g.styp(ret_typ)} ${tmp_var} = {.state=2, .err=${expr.name} };' )
2183
2183
} else {
2184
2184
mut simple_assign := false
2185
+ expr_typ_is_option := expr_typ.has_flag (.option)
2186
+ ret_typ_is_option := ret_typ.has_flag (.option)
2185
2187
if ret_typ.has_flag (.generic) {
2186
2188
if expr is ast.SelectorExpr && g.cur_concrete_types.len == 0 {
2187
2189
// 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
2203
2205
} else {
2204
2206
g.writeln ('${g.styp(ret_typ)} ${tmp_var} ;' )
2205
2207
}
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] {
2208
2210
simple_assign = expr is ast.StructInit
2209
2211
if simple_assign {
2210
2212
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
2214
2216
} else {
2215
2217
simple_assign =
2216
2218
((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 )
2218
2220
|| (expr_typ == ret_typ && ! (expr_typ.has_option_or_result ()
2219
2221
&& (expr_typ.is_ptr () || expr is ast.LambdaExpr )))
2220
2222
// option ptr assignment simplification
2221
2223
if simple_assign {
2222
2224
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
2224
2226
&& expr.right is ast.StructInit
2225
2227
&& (expr.right as ast.StructInit ).init_fields.len == 0 {
2226
2228
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
2243
2245
g.write ('_result_ok(&(${styp} []) { ' )
2244
2246
}
2245
2247
g.expr_with_cast (expr, expr_typ, ret_typ)
2246
- if ret_typ. has_flag (.option) {
2248
+ if ret_typ_is_option {
2247
2249
if simple_assign {
2248
2250
g.writeln (';' )
2249
2251
} else {
@@ -2448,8 +2450,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
2448
2450
if method.return_type.has_flag (.option) {
2449
2451
// Register an option if it's not registered yet
2450
2452
g.register_option (method.return_type)
2451
- }
2452
- if method.return_type.has_flag (.result) {
2453
+ } else if method.return_type.has_flag (.result) {
2453
2454
// Register a result if it's not registered yet
2454
2455
g.register_result (method.return_type)
2455
2456
}
@@ -2896,7 +2897,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
2896
2897
neither_void := ast.voidptr_type ! in [got_type, expected_type]
2897
2898
&& ast.nil_type ! in [got_type, expected_type]
2898
2899
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 ( ) {
2900
2901
shared_styp := exp_styp[0 ..exp_styp.len - 1 ] // `shared` implies ptr, so eat one `*`
2901
2902
if got_type_raw.is_ptr () {
2902
2903
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
2939
2940
return
2940
2941
}
2941
2942
}
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 () {
2944
2944
g.write ('(voidptr)' )
2945
2945
}
2946
2946
// no cast
@@ -3626,7 +3626,8 @@ fn (mut g Gen) expr(node_ ast.Expr) {
3626
3626
node.return_type.clear_option_and_result ()
3627
3627
}
3628
3628
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 {
3630
3631
ret_sym := g.table.sym (ret_type)
3631
3632
shared_typ := if ret_type.is_ptr () {
3632
3633
ret_type.deref ().set_flag (.shared_f)
@@ -3648,8 +3649,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
3648
3649
0
3649
3650
}
3650
3651
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 () {
3653
3653
g.write ('*' .repeat (ret_type.nr_muls ()))
3654
3654
}
3655
3655
g.call_expr (node)
@@ -3665,7 +3665,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
3665
3665
}
3666
3666
g.strs_to_free0 = []
3667
3667
}
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 {
3669
3669
g.writeln ('}, sizeof(${shared_styp} ))' )
3670
3670
}
3671
3671
/*
@@ -4524,10 +4524,10 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
4524
4524
cast_sym := g.table.sym (var_typ)
4525
4525
4526
4526
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)
4527
4529
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)
4531
4531
mut opt_cast := false
4532
4532
mut func := if cast_sym.info is ast.Aggregate {
4533
4533
''
@@ -4571,7 +4571,7 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
4571
4571
param_var.write_string ('.data)' )
4572
4572
}
4573
4573
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 {
4575
4575
param_var.write_string ('${obj.name} .data' )
4576
4576
} else {
4577
4577
param_var.write_string ('${obj.name} ' )
@@ -4581,15 +4581,15 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
4581
4581
values.write_string ('${func} (${param_var.str()} )}' )
4582
4582
} else {
4583
4583
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 {
4585
4585
// option unwrap
4586
4586
base_typ := g.base_type (obj.typ)
4587
4587
values.write_string ('${func} (*(${base_typ} *)${obj.name} .data)}' )
4588
4588
} else {
4589
4589
_ , str_method_expects_ptr , _ := cast_sym.str_method_info ()
4590
4590
4591
4591
// 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 {
4593
4593
''
4594
4594
} else if str_method_expects_ptr && ! obj.typ.is_ptr () {
4595
4595
'&'
@@ -5355,26 +5355,27 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
5355
5355
if g.comptime.is_comptime_expr (node.expr) {
5356
5356
expr_type = g.unwrap_generic (g.comptime.get_type (node.expr))
5357
5357
}
5358
+ node_typ_is_option := node.typ.has_flag (.option)
5358
5359
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 {
5360
5361
g.gen_option_error (node.typ, node.expr)
5361
5362
} else if node.expr is ast.Ident && g.comptime.is_comptime_variant_var (node.expr) {
5362
5363
g.expr_with_cast (node.expr, g.comptime.type_map['${g.comptime.comptime_for_variant_var} .typ' ],
5363
5364
node_typ)
5364
- } else if node.typ. has_flag (.option) {
5365
+ } else if node_typ_is_option {
5365
5366
g.expr_with_opt (node.expr, expr_type, node.typ)
5366
5367
} else {
5367
5368
g.expr_with_cast (node.expr, expr_type, node_typ)
5368
5369
}
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
5370
5371
&& ! sym.info.is_typedef {
5371
5372
// deprecated, replaced by Struct{...exr}
5372
5373
styp := g.styp (node.typ)
5373
5374
g.write ('*((${styp} *)(&' )
5374
5375
g.expr (node.expr)
5375
5376
g.write ('))' )
5376
5377
} 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 {
5378
5379
g.expr_with_opt (node.expr, expr_type, node.typ)
5379
5380
} else {
5380
5381
if node.expr is ast.ArrayInit && g.assign_op != .decl_assign {
@@ -5409,9 +5410,9 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
5409
5410
cast_label = '(${styp} )'
5410
5411
}
5411
5412
}
5412
- if node.typ. has_flag (.option) && node.expr is ast.None {
5413
+ if node_typ_is_option && node.expr is ast.None {
5413
5414
g.gen_option_error (node.typ, node.expr)
5414
- } else if node.typ. has_flag (.option) {
5415
+ } else if node_typ_is_option {
5415
5416
if sym.info is ast.Alias {
5416
5417
if sym.info.parent_type.has_flag (.option) {
5417
5418
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
6893
6894
} else {
6894
6895
mut is_array_fixed := false
6895
6896
mut return_wrapped := false
6897
+ mut return_is_option := is_option && return_type.has_option_or_result ()
6896
6898
if is_option {
6897
6899
is_array_fixed = g.table.final_sym (return_type).kind == .array_fixed
6898
6900
if ! is_array_fixed {
6899
6901
if g.inside_return && ! g.inside_struct_init
6900
6902
&& 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
6903
6904
&& expr_stmt.expr.or_block.kind == .absent {
6904
6905
g.write ('${cvar_name} = ' )
6905
6906
return_wrapped = true
@@ -6919,7 +6920,7 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
6919
6920
}
6920
6921
// return expr or { fn_returns_option() }
6921
6922
if is_option && g.inside_return && expr_stmt.expr is ast.CallExpr
6922
- && return_type. has_option_or_result () {
6923
+ && return_is_option {
6923
6924
g.expr_with_cast (expr_stmt.expr, expr_stmt.typ, return_type)
6924
6925
} else {
6925
6926
old_inside_opt_data := g.inside_opt_data
0 commit comments