@@ -1396,7 +1396,7 @@ fn (g &Gen) result_type_text(styp string, base string) string {
13961396fn (mut g Gen) register_option (t ast.Type) string {
13971397 styp , base := g.option_type_name (t)
13981398 g.options[base] = styp
1399- return styp
1399+ return if ! t. has_flag (.option_mut_param_t) { styp } else { '${ styp }*' }
14001400}
14011401
14021402fn (mut g Gen) register_result (t ast.Type) string {
@@ -2294,7 +2294,12 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
22942294 ret_styp := g.styp (unwrapped_ret_typ).replace ('*' , '_ptr' )
22952295 g.writeln ('${ret_styp } ${tmp_var };' )
22962296 } else {
2297- g.writeln ('${g .styp (ret_typ )} ${tmp_var };' )
2297+ if ret_typ.has_flag (.option_mut_param_t) {
2298+ ret_styp := g.styp (ret_typ).replace ('*' , '' )
2299+ g.writeln ('${ret_styp } ${tmp_var };' )
2300+ } else {
2301+ g.writeln ('${g .styp (ret_typ )} ${tmp_var };' )
2302+ }
22982303 }
22992304 mut expr_is_fixed_array_var := false
23002305 mut fn_option_clone := false
@@ -2336,8 +2341,21 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
23362341 }
23372342 }
23382343 if ! expr.is_literal () && expr_typ != ast.nil_type
2339- && ret_typ.nr_muls () > expr_typ.nr_muls () {
2344+ && ret_typ.nr_muls () > expr_typ.nr_muls ()
2345+ && ! ret_typ.has_flag (.option_mut_param_t) {
23402346 g.write ('&' .repeat (ret_typ.nr_muls () - expr_typ.nr_muls ()))
2347+ } else if ret_typ.has_flag (.option_mut_param_t) {
2348+ if expr_typ.is_ptr () {
2349+ if ret_typ.nr_muls () < expr_typ.nr_muls () {
2350+ g.write ('*' )
2351+ }
2352+ } else {
2353+ if expr_typ.has_flag (.option) {
2354+ fn_option_clone = true
2355+ g.write ('(${styp })' )
2356+ }
2357+ g.write ('&' )
2358+ }
23412359 }
23422360 }
23432361 } else {
@@ -3789,15 +3807,21 @@ fn (mut g Gen) expr(node_ ast.Expr) {
37893807 cur_line := g.go_before_last_stmt ().trim_space ()
37903808 mut expr_str := ''
37913809 mut is_unwrapped := true
3810+ mut dot_or_ptr := '.'
37923811 if mut node.expr is ast.ComptimeSelector && node.expr.left is ast.Ident {
37933812 // val.$(field.name)?
37943813 expr_str = g.gen_comptime_selector (node.expr)
37953814 } else if mut node.expr is ast.Ident && node.expr.ct_expr {
37963815 // val?
37973816 expr_str = node.expr.name
37983817 is_unwrapped = ! g.inside_assign
3818+ dot_or_ptr = if ! (node.expr.obj is ast.Var && node.expr.obj.is_auto_deref) {
3819+ '.'
3820+ } else {
3821+ '->'
3822+ }
37993823 }
3800- g.writeln ('if (${expr_str }. state != 0) {' )
3824+ g.writeln ('if (${expr_str }${ dot_or_ptr } state != 0) {' )
38013825 g.writeln2 ('\t panic_option_not_set(_S("none"));' , '}' )
38023826 g.write (cur_line)
38033827 if is_unwrapped {
@@ -5199,8 +5223,14 @@ fn (mut g Gen) ident(node ast.Ident) {
51995223 if ! g.is_assign_lhs && is_auto_heap {
52005224 g.write ('(*${name })' )
52015225 } else {
5202- if node.obj is ast.Var && node.obj.is_inherited {
5203- g.write (closure_ctx + '->' )
5226+ if node.obj is ast.Var {
5227+ // mutable option var
5228+ if (g.is_assign_lhs || g.inside_struct_init) && node.obj.is_auto_deref {
5229+ g.write ('*' )
5230+ }
5231+ if node.obj.is_inherited {
5232+ g.write (closure_ctx + '->' )
5233+ }
52045234 }
52055235 g.write (name)
52065236 }
@@ -5352,8 +5382,9 @@ fn (mut g Gen) ident(node ast.Ident) {
53525382 }
53535383 }
53545384 if i == 0 && node.obj.ct_type_var != .smartcast && node.obj.is_unwrapped {
5355- dot := if ! node.obj.ct_type_unwrapped && ! node.obj.orig_type.is_ptr ()
5356- && obj_sym.is_heap () {
5385+ dot := if (! node.obj.ct_type_unwrapped && ! node.obj.orig_type.is_ptr ()
5386+ && obj_sym.is_heap ())
5387+ || node.obj.orig_type.has_flag (.option_mut_param_t) {
53575388 '->'
53585389 } else {
53595390 '.'
@@ -7044,7 +7075,11 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
70447075// Returns the type of the last stmt
70457076fn (mut g Gen) or_block (var_name string , or_block ast.OrExpr, return_type ast.Type) {
70467077 cvar_name := c_name (var_name)
7047- tmp_op := if var_name in g.tmp_var_ptr { '->' } else { '.' }
7078+ tmp_op := if var_name in g.tmp_var_ptr || return_type.has_flag (.option_mut_param_t) {
7079+ '->'
7080+ } else {
7081+ '.'
7082+ }
70487083 if or_block.kind == .block && or_block.stmts.len == 0 {
70497084 // generate nothing, block is empty
70507085 g.write (';\n ${util .tabs (g .indent )}(void)${cvar_name };' )
0 commit comments