118
118
chan_pop_options map [string ]string // types for `x := <-ch or {...}`
119
119
chan_push_options map [string ]string // types for `ch <- x or {...}`
120
120
mtxs string // array of mutexes if the `lock` has multiple variables
121
+ tmp_var_ptr map [string ]bool // indicates if the tmp var passed to or_block() is a ptr
121
122
labeled_loops map [string ]& ast.Stmt
122
123
contains_ptr_cache map [ast.Type]bool
123
124
inner_loop & ast.Stmt = unsafe { nil }
@@ -4071,11 +4072,24 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
4071
4072
stmt_str := g.go_before_last_stmt ().trim_space ()
4072
4073
styp := g.styp (g.unwrap_generic (node.typ))
4073
4074
g.empty_line = true
4075
+ is_option_unwrap := node.typ.has_flag (.option)
4074
4076
tmp_var := g.new_tmp_var ()
4075
- g.write ('${styp} ${tmp_var} = ' )
4077
+ g.write ('${styp} ' )
4078
+ if is_option_unwrap {
4079
+ g.write ('*' )
4080
+ }
4081
+ g.write ('${tmp_var} = ' )
4076
4082
if is_ptr {
4077
4083
g.write ('*(' )
4078
4084
}
4085
+ needs_addr := is_option_unwrap && node.expr ! in [ast.Ident, ast.PrefixExpr]
4086
+ if is_option_unwrap {
4087
+ if ! needs_addr {
4088
+ g.write ('&' )
4089
+ } else {
4090
+ g.write ('ADDR(${styp} , ' )
4091
+ }
4092
+ }
4079
4093
g.expr (node.expr)
4080
4094
for i, embed in node.from_embed_types {
4081
4095
embed_sym := g.table.sym (embed)
@@ -4101,11 +4115,20 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
4101
4115
if is_ptr {
4102
4116
g.write (')' )
4103
4117
}
4118
+ if needs_addr {
4119
+ g.write (')' )
4120
+ }
4121
+ if is_option_unwrap {
4122
+ g.tmp_var_ptr[tmp_var] = true
4123
+ }
4104
4124
g.or_block (tmp_var, node.or_block, node.typ)
4125
+ if is_option_unwrap {
4126
+ g.tmp_var_ptr.delete (tmp_var)
4127
+ }
4105
4128
g.write2 (stmt_str, ' ' )
4106
4129
unwrapped_typ := node.typ.clear_option_and_result ()
4107
4130
unwrapped_styp := g.styp (unwrapped_typ)
4108
- g.write ('(*(${unwrapped_styp} *)${tmp_var} . data)' )
4131
+ g.write ('(*(${unwrapped_styp} *)${tmp_var} -> data)' )
4109
4132
return
4110
4133
}
4111
4134
@@ -6924,6 +6947,7 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
6924
6947
mut is_array_fixed := false
6925
6948
mut return_wrapped := false
6926
6949
mut return_is_option := is_option && return_type.has_option_or_result ()
6950
+ tmp_op := if cvar_name in g.tmp_var_ptr { '->' } else { '.' }
6927
6951
if is_option {
6928
6952
is_array_fixed = g.table.final_sym (return_type).kind == .array_fixed
6929
6953
if ! is_array_fixed {
@@ -6935,7 +6959,7 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
6935
6959
return_wrapped = true
6936
6960
} else if expr_stmt.expr is ast.CallExpr {
6937
6961
if expr_stmt.expr.is_return_used {
6938
- g.write ('*(${cast_typ} *) ${cvar_name} . data = ' )
6962
+ g.write ('*(${cast_typ} *) ${cvar_name}${tmp_op} data = ' )
6939
6963
}
6940
6964
} else if g.inside_opt_or_res && return_is_option && g.inside_assign {
6941
6965
g.write ('_option_ok(&(${cast_typ} []) { ' )
@@ -6944,14 +6968,14 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
6944
6968
g.indent--
6945
6969
return
6946
6970
} else {
6947
- g.write ('*(${cast_typ} *) ${cvar_name} . data = ' )
6971
+ g.write ('*(${cast_typ} *) ${cvar_name}${tmp_op} data = ' )
6948
6972
}
6949
6973
}
6950
6974
} else {
6951
6975
g.write ('${cvar_name} = ' )
6952
6976
}
6953
6977
if is_array_fixed {
6954
- g.write ('memcpy(${cvar_name} . data, (${cast_typ} )' )
6978
+ g.write ('memcpy(${cvar_name}${tmp_op} data, (${cast_typ} )' )
6955
6979
}
6956
6980
// return expr or { fn_returns_option() }
6957
6981
if is_option && g.inside_return && expr_stmt.expr is ast.CallExpr
@@ -6987,6 +7011,7 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
6987
7011
// Returns the type of the last stmt
6988
7012
fn (mut g Gen) or_block (var_name string , or_block ast.OrExpr, return_type ast.Type) {
6989
7013
cvar_name := c_name (var_name)
7014
+ tmp_op := if var_name in g.tmp_var_ptr { '->' } else { '.' }
6990
7015
if or_block.kind == .block && or_block.stmts.len == 0 {
6991
7016
// generate nothing, block is empty
6992
7017
g.write (';\n ${util.tabs(g.indent)} (void)${cvar_name} ;' )
@@ -6996,20 +7021,20 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
6996
7021
is_none_ok := return_type == ast.ovoid_type
6997
7022
g.writeln (';' )
6998
7023
if is_none_ok {
6999
- g.writeln ('if (${cvar_name} . state != 0) {' )
7024
+ g.writeln ('if (${cvar_name}${tmp_op} state != 0) {' )
7000
7025
} else {
7001
7026
if return_type != 0 && g.table.sym (return_type).kind == .function {
7002
7027
mr_styp = 'voidptr'
7003
7028
}
7004
7029
if return_type.has_flag (.result) {
7005
- g.writeln ('if (${cvar_name} . is_error) {' )
7030
+ g.writeln ('if (${cvar_name}${tmp_op} is_error) {' )
7006
7031
} else {
7007
- g.writeln ('if (${cvar_name} . state != 0) {' )
7032
+ g.writeln ('if (${cvar_name}${tmp_op} state != 0) {' )
7008
7033
}
7009
7034
}
7010
7035
if or_block.kind == .block {
7011
7036
g.or_expr_return_type = return_type.clear_option_and_result ()
7012
- g.writeln ('\t IError err = ${cvar_name} . err;' )
7037
+ g.writeln ('\t IError err = ${cvar_name}${tmp_op} err;' )
7013
7038
7014
7039
g.inside_or_block = true
7015
7040
defer {
@@ -7029,7 +7054,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
7029
7054
|| (or_block.kind == .propagate_option && return_type.has_flag (.result)) {
7030
7055
if g.file.mod.name == 'main' && (g.fn_decl == unsafe { nil } || g.fn_decl.is_main) {
7031
7056
// In main(), an `opt()!` call is sugar for `opt() or { panic(err) }`
7032
- err_msg := 'IError_name_table[${cvar_name} . err._typ]._method_msg(${cvar_name} . err._object)'
7057
+ err_msg := 'IError_name_table[${cvar_name}${tmp_op} err._typ]._method_msg(${cvar_name}${tmp_op} err._object)'
7033
7058
if g.pref.is_debug {
7034
7059
paline , pafile , pamod , pafn := g.panic_debug_info (or_block.pos)
7035
7060
g.writeln ('panic_debug(${paline} , tos3("${pafile} "), tos3("${pamod} "), tos3("${pafn} "), ${err_msg} );' )
@@ -7057,7 +7082,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
7057
7082
} else if or_block.kind == .propagate_option {
7058
7083
if g.file.mod.name == 'main' && (g.fn_decl == unsafe { nil } || g.fn_decl.is_main) {
7059
7084
// In main(), an `opt()?` call is sugar for `opt() or { panic(err) }`
7060
- err_msg := 'IError_name_table[${cvar_name} . err._typ]._method_msg(${cvar_name} . err._object)'
7085
+ err_msg := 'IError_name_table[${cvar_name}${tmp_op} err._typ]._method_msg(${cvar_name}${tmp_op} err._object)'
7061
7086
if g.pref.is_debug {
7062
7087
paline , pafile , pamod , pafn := g.panic_debug_info (or_block.pos)
7063
7088
g.writeln ('panic_debug(${paline} , tos3("${pafile} "), tos3("${pamod} "), tos3("${pafn} "), ${err_msg} .len == 0 ? _SLIT("option not set ()") : ${err_msg} );' )
0 commit comments