From 267475d919454faf39dc54db1f7b802fe86698fa Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Fri, 24 Apr 2026 01:19:21 +0300 Subject: [PATCH] checker: fix Regression: V can't match generics variant (fixes #26866) --- vlib/v/checker/match.v | 14 ++++--- .../tests/generics/generic_match_expr_test.v | 38 +++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index 32abe707a..2c100d4ff 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -703,6 +703,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym mut expr_types := []ast.TypeNode{} for k, mut expr in branch.exprs { mut key := '' + mut resolved_type_node := ast.no_type // TODO: investigate why enums are different here: if expr !is ast.EnumVal && !(node.is_comptime && expr is ast.ComptimeType) { // ensure that the sub expressions of the branch are actually checked, before anything else: @@ -787,12 +788,11 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym is_type_node := expr is ast.TypeNode || expr is ast.ComptimeType match mut expr { ast.TypeNode { - expr_typ := c.recheck_concrete_type(expr.typ) - key = c.table.type_to_str(expr_typ) - expr.typ = expr_typ + resolved_type_node = c.recheck_concrete_type(expr.typ) + key = c.table.type_to_str(resolved_type_node) expr_types << ast.TypeNode{ ...expr - typ: expr_typ + typ: resolved_type_node } } ast.EnumVal { @@ -875,7 +875,11 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym } } } else { - expr_type := c.expr(mut expr) + expr_type := if expr is ast.TypeNode { + resolved_type_node + } else { + c.expr(mut expr) + } if expr_type.idx() == 0 { // parser failed, stop checking return diff --git a/vlib/v/tests/generics/generic_match_expr_test.v b/vlib/v/tests/generics/generic_match_expr_test.v index a6188b2c2..303404489 100644 --- a/vlib/v/tests/generics/generic_match_expr_test.v +++ b/vlib/v/tests/generics/generic_match_expr_test.v @@ -22,3 +22,41 @@ fn test_main() { t('')! assert true } + +type GenericMatchSumtype[T] = GenericMatchY[T] | GenericMatchZ[T] + +fn (mut x GenericMatchSumtype[T]) do_it[T]() string { + match mut x { + GenericMatchY[T] { return 'doing GenericMatchY' } + GenericMatchZ[T] { return 'doing GenericMatchZ' } + } + + return '' +} + +struct GenericMatchY[T] { + name string + value T +} + +struct GenericMatchZ[T] { + name string + value T +} + +fn test_match_generic_sumtype_variant_in_generic_method() { + y := GenericMatchY[int]{ + name: 'Y' + value: 1 + } + z := GenericMatchZ[bool]{ + name: 'Z' + value: true + } + + mut x1 := GenericMatchSumtype[int](y) + assert x1.do_it() == 'doing GenericMatchY' + + mut x2 := GenericMatchSumtype[bool](z) + assert x2.do_it() == 'doing GenericMatchZ' +} -- 2.39.5