From 7596b52c1db0016d2c9a3460d58a957bd7160b07 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 29 Apr 2026 21:10:23 +0300 Subject: [PATCH] cgen, markused: fixes --- vlib/v/gen/c/utils.v | 4 +- vlib/v/markused/walker.v | 3 ++ .../generic_fn_instantiation_pruning_test.v | 51 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/vlib/v/gen/c/utils.v b/vlib/v/gen/c/utils.v index ce9709bbd..1401dee00 100644 --- a/vlib/v/gen/c/utils.v +++ b/vlib/v/gen/c/utils.v @@ -387,7 +387,9 @@ fn (mut g Gen) is_expr_smartcast_to_sumtype(expr ast.Expr, expected_sumtype ast. if expr is ast.SelectorExpr { v := scope.find_struct_field(expr.expr.str(), expr.expr_type, expr.field_name) if v != unsafe { nil } && v.smartcasts.len > 0 { - return true + orig_type := g.unwrap_generic(g.recheck_concrete_type(v.orig_type)) + resolved_expected_sumtype := g.unwrap_generic(g.recheck_concrete_type(expected_sumtype)) + return orig_type == resolved_expected_sumtype } } else if expr is ast.Ident { if v := scope.find_var(expr.name) { diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index dc27c784a..6f2cd3d47 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -3223,6 +3223,9 @@ fn (mut w Walker) mark_generic_body_dependencies_in_stmts(stmts []ast.Stmt) { fn (mut w Walker) mark_generic_body_dependencies_in_expr(expr_ ast.Expr) { expr := unsafe { expr_ } match expr { + ast.AnonFn { + w.mark_generic_body_dependencies_in_stmts(expr.decl.stmts) + } ast.CallExpr { w.mark_direct_non_generic_call(expr) w.mark_generic_body_dependencies_in_expr(expr.left) diff --git a/vlib/v/tests/skip_unused/generic_fn_instantiation_pruning_test.v b/vlib/v/tests/skip_unused/generic_fn_instantiation_pruning_test.v index 6d158766e..d20e97fc8 100644 --- a/vlib/v/tests/skip_unused/generic_fn_instantiation_pruning_test.v +++ b/vlib/v/tests/skip_unused/generic_fn_instantiation_pruning_test.v @@ -124,3 +124,54 @@ fn test_skip_unused_keeps_json2_embedded_struct_decode_helpers() { assert res.output.contains('x__json2__check_required_struct_fields_T_main__Req') assert res.output.contains('x__json2__create_value_from_optional_T_time__Time') } + +fn test_skip_unused_marks_dependencies_inside_generic_anon_fns() { + tmp_dir := os.join_path(os.vtmp_dir(), 'v_generic_anon_fn_dependencies') + os.mkdir_all(tmp_dir) or { panic(err) } + defer { + os.rmdir_all(tmp_dir) or {} + } + source_path := os.join_path(tmp_dir, 'generic_anon_fn_dependencies.v') + binary_path := os.join_path(tmp_dir, 'generic_anon_fn_dependencies') + source := [ + 'module main', + '', + 'struct Holder[T] {', + '\tdata []T', + '}', + '', + 'fn (h &Holder[T]) nmap[T](others []&Holder[T], f fn ([]T) T) T {', + '\treturn f([h.data[0], others[0].data[0]])', + '}', + '', + 'fn (a &Holder[T]) subtract[T](b &Holder[T]) T {', + '\treturn a.nmap([b], fn [T] (xs []T) T {', + '\t\tx := xs[0]', + '\t\ty := xs[1]', + '\t\t$if T is string {', + "\t\t\treturn x.replace(y, '')", + '\t\t} $else {', + '\t\t\treturn x - y', + '\t\t}', + '\t})', + '}', + '', + 'fn unused_string() {', + "\ta := &Holder[string]{data: ['abc']}", + "\tb := &Holder[string]{data: ['b']}", + '\tprintln(a.subtract(b))', + '}', + '', + 'fn main() {', + '\ta := &Holder[int]{data: [1]}', + '\tb := &Holder[int]{data: [2]}', + '\tprintln(a.subtract(b))', + '}', + ].join('\n') + os.write_file(source_path, source) or { panic(err) } + res := + os.execute('${os.quoted_path(vexe)} -d no_backtrace -o ${os.quoted_path(binary_path)} ${os.quoted_path(source_path)}') + if res.exit_code != 0 { + panic(res.output) + } +} -- 2.39.5