From b17ac3384a13af1ee0a02aa18d8170e05e8db8aa Mon Sep 17 00:00:00 2001 From: imperivox Date: Sun, 23 Nov 2025 19:37:32 +0100 Subject: [PATCH] checker: allow explicit sumtype to option casts (fix #25796) (#25812) --- vlib/v/checker/checker.v | 7 +++++++ .../option_sumtype_explicit_cast_test.v | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 vlib/v/tests/options/option_sumtype_explicit_cast_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index c6f39130d..691bd3a4d 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3547,8 +3547,15 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { if from_type == ast.void_type { c.error('expression does not return a value so it cannot be cast', node.expr.pos()) } + inner_to_type := if to_type.has_flag(.option) { + to_type.clear_flag(.option) + } else { + ast.void_type + } if to_type.has_flag(.option) && from_type == ast.none_type { // allow conversion from none to every option type + } else if to_type.has_flag(.option) && from_type == inner_to_type { + return to_type } else if to_sym.kind == .sum_type { to_sym_info := to_sym.info as ast.SumType if c.pref.skip_unused && to_sym_info.concrete_types.len > 0 { diff --git a/vlib/v/tests/options/option_sumtype_explicit_cast_test.v b/vlib/v/tests/options/option_sumtype_explicit_cast_test.v new file mode 100644 index 000000000..5eb9ffd5e --- /dev/null +++ b/vlib/v/tests/options/option_sumtype_explicit_cast_test.v @@ -0,0 +1,19 @@ +type SumType = u16 | u32 + +fn wrap[T](x T) ?T { + return ?T(x) +} + +fn test_sumtype_explicit_to_option_sumtype() { + value := SumType(u16(0)) + a := ?SumType(value) + assert a != none + assert a? == SumType(u16(0)) +} + +fn test_sumtype_explicit_to_option_sumtype_generic() { + value := SumType(u16(1)) + a := wrap[SumType](value) + assert a != none + assert a? == SumType(u16(1)) +} -- 2.39.5