174174 inside_for_c_stmt bool
175175 inside_cast_in_heap int // inside cast to interface type in heap (resolve recursive calls)
176176 inside_cast bool
177+ inside_interface_cast bool
177178 inside_sumtype_cast bool
178179 inside_selector bool
179180 inside_selector_lhs bool
@@ -4510,6 +4511,8 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Ty
45104511 } else {
45114512 old_inside_sumtype_cast := g.inside_sumtype_cast
45124513 g.inside_sumtype_cast = true
4514+ old_inside_interface_cast := g.inside_interface_cast
4515+ g.inside_interface_cast = g.inside_interface_cast || is_interface_cast
45134516 old_left_is_opt := g.left_is_opt
45144517 g.left_is_opt = ! exp.has_flag (.option)
45154518 old_inside_assign_fn_var := g.inside_assign_fn_var
@@ -4525,6 +4528,7 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Ty
45254528 }
45264529 g.inside_assign_fn_var = old_inside_assign_fn_var
45274530 g.left_is_opt = old_left_is_opt
4531+ g.inside_interface_cast = old_inside_interface_cast
45284532 g.inside_sumtype_cast = old_inside_sumtype_cast
45294533 }
45304534 if is_sumtype_cast {
@@ -9105,6 +9109,11 @@ fn (mut g Gen) ident(node ast.Ident) {
91059109 }
91069110 }
91079111 }
9112+ ident_option_name := if has_resolved_var && resolved_var.is_inherited {
9113+ '${closure_ctx} ->${name} '
9114+ } else {
9115+ name
9116+ }
91089117 if node.info is ast.IdentVar {
91099118 node_info_is_option = node.info.is_option
91109119 if node.or_expr.kind == .absent {
@@ -9155,7 +9164,7 @@ fn (mut g Gen) ident(node ast.Ident) {
91559164 if orig_has_option && ! comptime_type.has_flag (.option) {
91569165 styp := g.base_type (comptime_type)
91579166 ptr := if is_auto_heap { '->' } else { '.' }
9158- g.write ('(*(${styp} *)${name }${ptr} data)' )
9167+ g.write ('(*(${styp} *)${ident_option_name }${ptr} data)' )
91599168 } else if comptime_type.has_flag (.option) {
91609169 if (g.inside_opt_or_res || g.left_is_opt) && node.or_expr.kind == .absent {
91619170 if ! g.is_assign_lhs && is_auto_heap {
@@ -9166,7 +9175,7 @@ fn (mut g Gen) ident(node ast.Ident) {
91669175 } else {
91679176 styp := g.base_type (comptime_type)
91689177 ptr := if is_auto_heap { '->' } else { '.' }
9169- g.write ('(*(${styp} *)${name }${ptr} data)' )
9178+ g.write ('(*(${styp} *)${ident_option_name }${ptr} data)' )
91709179 }
91719180 } else {
91729181 emit_auto_heap_deref := is_auto_heap && ! g.inside_assign_fn_var
@@ -9222,7 +9231,8 @@ fn (mut g Gen) ident(node ast.Ident) {
92229231 g.write ('*(' )
92239232 }
92249233 if ! has_smartcast && ! selector_uses_unwrapped_option_smartcast
9225- && (g.inside_opt_or_res || g.left_is_opt) && node.or_expr.kind == .absent {
9234+ && (g.inside_opt_or_res || (g.left_is_opt && ! g.inside_interface_cast))
9235+ && node.or_expr.kind == .absent {
92269236 if ! g.is_assign_lhs && is_auto_heap {
92279237 g.write ('(*${name} )' )
92289238 } else {
@@ -9256,7 +9266,7 @@ fn (mut g Gen) ident(node ast.Ident) {
92569266 } else {
92579267 g.get_comptime_for_var_type (node, node.info.typ)
92589268 }
9259- g.unwrap_option_type (unwrap_typ, name , is_auto_heap)
9269+ g.unwrap_option_type (unwrap_typ, ident_option_name , is_auto_heap)
92609270 }
92619271 if node.or_expr.kind != .absent && ! (g.inside_opt_or_res && g.inside_assign
92629272 && ! g.is_assign_lhs) {
@@ -9336,6 +9346,20 @@ fn (mut g Gen) ident(node ast.Ident) {
93369346 }
93379347 }
93389348 is_option = is_option || (has_resolved_var && resolved_var.orig_type.has_flag (.option))
9349+ runtime_option_type := if resolved_var.orig_type.has_flag (.option) {
9350+ resolved_var.orig_type
9351+ } else if resolved_var.typ.has_flag (.option) {
9352+ resolved_var.typ
9353+ } else {
9354+ ast.no_type
9355+ }
9356+ if has_resolved_var && runtime_option_type != ast.no_type && ! node_info_is_option
9357+ && resolved_var.smartcasts.len == 0 && resolved_var.ct_type_var != .smartcast
9358+ && ! g.inside_opt_or_res && ! g.is_assign_lhs && ! g.inside_selector_lhs
9359+ && ! g.right_is_opt && (! g.left_is_opt || g.inside_cast || g.inside_interface_cast) {
9360+ g.unwrap_option_type (runtime_option_type, ident_option_name, is_auto_heap)
9361+ return
9362+ }
93399363 // When an auto-heap option variable is being smartcast-unwrapped
93409364 // (e.g. `if svc != none { use(svc) }`), the option unwrap code
93419365 // at `->data` already handles the pointer indirection. Skip the
@@ -9594,13 +9618,13 @@ fn (mut g Gen) ident(node ast.Ident) {
95949618 if g.inside_selector_lhs && ! node_info_is_option && has_resolved_var
95959619 && ! resolved_var.is_unwrapped && resolved_var.smartcasts.len == 0
95969620 && resolved_var.typ.has_flag (.option) && ! g.is_assign_lhs {
9597- g.unwrap_option_type (resolved_var.typ, name , is_auto_heap)
9621+ g.unwrap_option_type (resolved_var.typ, ident_option_name , is_auto_heap)
95989622 return
95999623 }
96009624 if g.inside_selector_lhs && has_resolved_var && resolved_var.is_unwrapped
96019625 && resolved_var.smartcasts.len == 0 && resolved_var.orig_type.has_flag (.option)
96029626 && ! g.is_assign_lhs {
9603- g.unwrap_option_type (resolved_var.orig_type, name , is_auto_heap)
9627+ g.unwrap_option_type (resolved_var.orig_type, ident_option_name , is_auto_heap)
96049628 return
96059629 }
96069630 if has_resolved_var && resolved_var.is_inherited {
0 commit comments