diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 7bb67c003aae62..6a1e6d31a641a3 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4312,7 +4312,9 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast. mut orig_type := 0 mut is_inherited := false mut ct_type_var := ast.ComptimeVarKind.no_comptime + mut is_ct_type_unwrapped := false if mut expr.obj is ast.Var { + is_ct_type_unwrapped = expr.obj.ct_type_var != ast.ComptimeVarKind.no_comptime is_mut = expr.obj.is_mut smartcasts << expr.obj.smartcasts is_already_casted = expr.obj.pos.pos == expr.pos.pos @@ -4334,16 +4336,17 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast. if cur_type.has_flag(.option) && !to_type.has_flag(.option) { if !var.is_unwrapped { scope.register(ast.Var{ - name: expr.name - typ: cur_type - pos: expr.pos - is_used: true - is_mut: expr.is_mut - is_inherited: is_inherited - smartcasts: [to_type] - orig_type: orig_type - ct_type_var: ct_type_var - is_unwrapped: true + name: expr.name + typ: cur_type + pos: expr.pos + is_used: true + is_mut: expr.is_mut + is_inherited: is_inherited + smartcasts: [to_type] + orig_type: orig_type + ct_type_var: ct_type_var + ct_type_unwrapped: is_ct_type_unwrapped + is_unwrapped: true }) } else { scope.update_smartcasts(expr.name, to_type, true) @@ -4355,16 +4358,17 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast. } } scope.register(ast.Var{ - name: expr.name - typ: cur_type - pos: expr.pos - is_used: true - is_mut: expr.is_mut - is_inherited: is_inherited - is_unwrapped: is_option_unwrap - smartcasts: smartcasts - orig_type: orig_type - ct_type_var: ct_type_var + name: expr.name + typ: cur_type + pos: expr.pos + is_used: true + is_mut: expr.is_mut + is_inherited: is_inherited + is_unwrapped: is_option_unwrap + smartcasts: smartcasts + orig_type: orig_type + ct_type_var: ct_type_var + ct_type_unwrapped: is_ct_type_unwrapped }) } else if is_mut && !expr.is_mut { c.smartcast_mut_pos = expr.pos diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 29b032fdec7229..9d1a9b39c0bd5b 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5158,7 +5158,8 @@ fn (mut g Gen) ident(node ast.Ident) { } } if i == 0 && node.obj.ct_type_var != .smartcast && node.obj.is_unwrapped { - dot := if !node.obj.orig_type.is_ptr() && obj_sym.is_heap() { + dot := if !node.obj.ct_type_unwrapped && !node.obj.orig_type.is_ptr() + && obj_sym.is_heap() { '->' } else { '.' diff --git a/vlib/v/tests/comptime/comptime_var_unwrap_test.v b/vlib/v/tests/comptime/comptime_var_unwrap_test.v new file mode 100644 index 00000000000000..4a095eb41c98cf --- /dev/null +++ b/vlib/v/tests/comptime/comptime_var_unwrap_test.v @@ -0,0 +1,26 @@ +struct Foo { + a int +} + +fn Foo.init[T](a T) { + dump(a) +} + +@[heap] +struct Bar { + field int +} + +fn t[T](a ?T) T { + mut b := a + if b != none { + Foo.init(b) + return b + } + assert false + return T{} +} + +fn test_main() { + assert t(Bar{}) == Bar{} +}