From 8eba7b2bf5e012a775c2bee9c7f88ea66fc9938d Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Thu, 31 Jul 2025 08:32:33 +0300 Subject: [PATCH] Revert "markused: clean up features tracking from checker - remove 1 all_fns loop (#24999)" This reverts commit 844b7007a7db22d5e470dade941eb6874777e6c5. --- vlib/v/ast/table.v | 5 +- vlib/v/checker/checker.v | 2 + vlib/v/checker/fn.v | 2 +- vlib/v/checker/infix.v | 1 + vlib/v/checker/used_features.v | 44 ++++------ vlib/v/gen/c/dumpexpr.v | 4 - vlib/v/markused/markused.v | 50 ++++++++++- vlib/v/markused/walker.v | 155 +++++++++------------------------ 8 files changed, 114 insertions(+), 149 deletions(-) diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index b3ece061e9..f962fcfcc2 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -10,12 +10,13 @@ import v.util @[heap; minify] pub struct UsedFeatures { pub mut: - dump bool // filled in by markused + dump bool // dump() + index bool // string[0] range_index bool // string[0..1] + cast_ptr bool // &u8(...) anon_fn bool // fn () { } auto_str bool // auto str fns auto_str_ptr bool // auto str fns for ptr type - auto_str_arr bool // auto str fns for array arr_prepend bool // arr.prepend() arr_insert bool // arr.insert() arr_first bool // arr.first() diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index bda2d44f55..7129a46d4c 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3069,6 +3069,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { return c.concat_expr(mut node) } ast.DumpExpr { + c.table.used_features.dump = true c.expected_type = ast.string_type node.expr_type = c.expr(mut node.expr) c.markused_dumpexpr(mut node) @@ -5013,6 +5014,7 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { if node.index is ast.RangeExpr { c.table.used_features.range_index = true } + c.table.used_features.index = true } is_aggregate_arr := typ_sym.kind == .aggregate && (typ_sym.info as ast.Aggregate).types.filter(c.table.type_kind(it) !in [.array, .array_fixed, .string, .map]).len == 0 diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index da4386d498..18996c05db 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1441,7 +1441,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. if args_len > 0 && fn_name in print_everything_fns { node.args[0].ct_expr = c.comptime.is_comptime(node.args[0].expr) c.builtin_args(mut node, fn_name, func) - c.markused_print_call(mut node) + c.markused_fn_call(mut node) return func.return_type } // `return error(err)` -> `return err` diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 6378677a53..24314b9a34 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -60,6 +60,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { if left_type.has_flag(.option) { c.error('cannot push to Option array that was not unwrapped first', node.left.pos()) } + c.markused_infixexpr(!c.is_builtin_mod && c.mod != 'strings') if mut node.right is ast.IfExpr { if node.right.is_expr && node.right.branches.len > 0 { mut last_stmt := node.right.branches[0].stmts.last() diff --git a/vlib/v/checker/used_features.v b/vlib/v/checker/used_features.v index 80679d0711..43139777e9 100644 --- a/vlib/v/checker/used_features.v +++ b/vlib/v/checker/used_features.v @@ -36,9 +36,6 @@ fn (mut c Checker) markused_dumpexpr(mut node ast.DumpExpr) { if node.expr_type.is_ptr() { c.table.used_features.auto_str_ptr = true } - if !c.table.used_features.auto_str_arr { - c.table.used_features.auto_str_arr = c.table.final_sym(unwrapped_type).kind == .array - } } else { c.table.used_features.print_types[node.expr_type.idx()] = true } @@ -61,6 +58,9 @@ fn (mut c Checker) markused_castexpr(mut node ast.CastExpr, to_type ast.Type, mu c.table.used_features.used_maps++ } } + if c.mod !in ['strings', 'math.bits'] && to_type.is_ptr() { + c.table.used_features.cast_ptr = true + } } fn (mut c Checker) markused_comptimecall(mut node ast.ComptimeCall) { @@ -91,6 +91,7 @@ fn (mut c Checker) markused_comptimecall(mut node ast.ComptimeCall) { } fn (mut c Checker) markused_comptimefor(mut node ast.ComptimeFor, unwrapped_expr_type ast.Type) { + c.table.used_features.dump = true if c.table.used_features.used_maps == 0 { final_sym := c.table.final_sym(unwrapped_expr_type) if final_sym.info is ast.Map { @@ -107,45 +108,34 @@ fn (mut c Checker) markused_call_expr(left_type ast.Type, mut node ast.CallExpr) if left_type != 0 && left_type.is_ptr() && !c.table.used_features.auto_str_ptr && node.name == 'str' { c.table.used_features.auto_str_ptr = true - if !c.table.used_features.auto_str_arr { - c.table.used_features.auto_str_arr = c.table.final_sym(left_type).kind == .array - } } } -fn (mut c Checker) markused_print_call(mut node ast.CallExpr) { +fn (mut c Checker) markused_fn_call(mut node ast.CallExpr) { if !c.is_builtin_mod && c.mod != 'math.bits' && node.args[0].expr !is ast.StringLiteral { - arg_typ := c.unwrap_generic(node.args[0].typ) if (node.args[0].expr is ast.CallExpr && node.args[0].expr.is_method && node.args[0].expr.name == 'str') - || !c.table.sym(arg_typ).has_method('str') { + || !c.table.sym(c.unwrap_generic(node.args[0].typ)).has_method('str') { c.table.used_features.auto_str = true } else { - if arg_typ.has_option_or_result() { + if node.args[0].typ.has_option_or_result() { c.table.used_features.print_options = true } - c.table.used_features.print_types[arg_typ.idx()] = true + c.table.used_features.print_types[node.args[0].typ.idx()] = true if !c.table.used_features.auto_str_ptr && node.args[0].expr is ast.Ident { var_obj := node.args[0].expr.obj if var_obj is ast.Var { - if var_obj.orig_type != 0 { - fsym := c.table.final_sym(var_obj.orig_type) - if fsym.kind == .interface { - c.table.used_features.auto_str_ptr = true - } else if fsym.kind == .array { - c.table.used_features.auto_str_arr = true - } + if var_obj.orig_type != 0 + && c.table.final_sym(var_obj.orig_type).kind == .interface { + c.table.used_features.auto_str_ptr = true return } } } } - if arg_typ.is_ptr() { + if node.args[0].typ.is_ptr() { c.table.used_features.auto_str_ptr = true } - if !c.table.used_features.auto_str_arr { - c.table.used_features.auto_str_arr = c.table.final_sym(arg_typ).kind == .array - } } } @@ -175,14 +165,18 @@ fn (mut c Checker) markused_string_inter_lit(mut node ast.StringInterLiteral, ft if ftyp.is_ptr() { c.table.used_features.auto_str_ptr = true } - if !c.table.used_features.auto_str_arr { - c.table.used_features.auto_str_arr = c.table.final_sym(ftyp).kind == .array - } if ftyp.has_option_or_result() { c.table.used_features.print_options = true } } +fn (mut c Checker) markused_infixexpr(check bool) { + if !check { + return + } + c.table.used_features.index = true +} + fn (mut c Checker) markused_array_method(check bool, method_name string) { if !check { return diff --git a/vlib/v/gen/c/dumpexpr.v b/vlib/v/gen/c/dumpexpr.v index b508b54d82..727948354a 100644 --- a/vlib/v/gen/c/dumpexpr.v +++ b/vlib/v/gen/c/dumpexpr.v @@ -107,10 +107,6 @@ fn (mut g Gen) dump_expr_definitions() { } _, str_method_expects_ptr, _ := dump_sym.str_method_info() typ := ast.idx_to_type(dump_type) - if g.pref.skip_unused - && (!g.table.used_features.dump || typ.idx() !in g.table.used_features.used_syms) { - continue - } is_ptr := typ.is_ptr() deref, _ := deref_kind(str_method_expects_ptr, is_ptr, typ) to_string_fn_name := g.get_str_fn(typ.clear_flags(.shared_f, .result)) diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index 02a883fb1d..c78b7061b5 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -85,6 +85,21 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a core_fns << '__new_array_with_array_default_noscan' core_fns << 'new_array_from_c_array' } + if table.used_features.index || pref_.is_shared { + include_panic_deps = true + core_fns << string_idx_str + '.at_with_check' + core_fns << string_idx_str + '.clone' + core_fns << string_idx_str + '.clone_static' + core_fns << string_idx_str + '.at' + core_fns << array_idx_str + '.set' + core_fns << array_idx_str + '.get_with_check' // used for `x := a[i] or {}` + core_fns << ref_array_idx_str + '.set' + core_fns << map_idx_str + '.get' + core_fns << map_idx_str + '.set' + core_fns << '__new_array_noscan' + core_fns << ref_array_idx_str + '.push_noscan' + core_fns << ref_array_idx_str + '.push_many_noscan' + } if table.used_features.range_index || pref_.is_shared { core_fns << string_idx_str + '.substr_with_check' core_fns << string_idx_str + '.substr_ni' @@ -94,6 +109,10 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a core_fns << array_idx_str + '.clone_static_to_depth' core_fns << array_idx_str + '.clone_to_depth' } + if table.used_features.auto_str || table.used_features.dump { + core_fns << string_idx_str + '.repeat' + core_fns << 'tos3' + } if table.used_features.arr_prepend { core_fns << ref_array_idx_str + '.prepend_many' } @@ -102,7 +121,6 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a } if table.used_features.arr_pop { core_fns << ref_array_idx_str + '.pop' - core_fns << ref_array_idx_str + '.pop_noscan' } if table.used_features.arr_first { core_fns << array_idx_str + '.first' @@ -112,7 +130,15 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a } if table.used_features.arr_insert { core_fns << ref_array_idx_str + '.insert_many' - core_fns << ref_array_idx_str + '.insert_noscan' + } + if table.used_features.dump { + include_panic_deps = true + builderptr_idx := int(table.find_type('strings.Builder').ref()).str() + core_fns << [ + builderptr_idx + '.str', + builderptr_idx + '.free', + builderptr_idx + '.write_rune', + ] } if table.used_features.print_options { include_panic_deps = true @@ -259,6 +285,26 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a handle_vweb(mut table, mut all_fn_root_names, 'vweb.Result', 'vweb.filter', 'vweb.Context') handle_vweb(mut table, mut all_fn_root_names, 'x.vweb.Result', 'x.vweb.filter', 'x.vweb.Context') + // handle ORM drivers: + orm_connection_implementations := table.iface_types['orm.Connection'] or { []ast.Type{} } + if orm_connection_implementations.len > 0 { + for k, _ in all_fns { + if k.starts_with('orm.') { + all_fn_root_names << k + } + } + for orm_type in orm_connection_implementations { + typ := int(orm_type).str() + all_fn_root_names << typ + '.select' + all_fn_root_names << typ + '.insert' + all_fn_root_names << typ + '.update' + all_fn_root_names << typ + '.delete' + all_fn_root_names << typ + '.create' + all_fn_root_names << typ + '.drop' + all_fn_root_names << typ + '.last_id' + } + } + if 'debug_used_features' in pref_.compile_defines { eprintln('> debug_used_features: ${table.used_features}') } diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index c3fc346942..e9ce833eec 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -30,9 +30,8 @@ mut: all_decltypes map[string]ast.TypeDecl all_structs map[string]ast.StructDecl - level int - is_builtin_mod bool - is_direct_array_access bool + level int + is_builtin_mod bool // dependencies finding flags uses_atomic bool // has atomic @@ -61,11 +60,6 @@ mut: uses_dump bool uses_memdup bool // sumtype cast and &Struct{} uses_arr_void bool // auto arr methods - uses_index bool // var[k] - uses_str_index bool // string[k] - uses_fixed_arr_int bool // fixed_arr[k] - uses_check_index bool // arr[key] or { } - uses_append bool // var << item } pub fn Walker.new(params Walker) &Walker { @@ -77,7 +71,7 @@ pub fn Walker.new(params Walker) &Walker { } @[inline] -fn (mut w Walker) mark_fn_as_used(fkey string) { +pub fn (mut w Walker) mark_fn_as_used(fkey string) { $if trace_skip_unused_marked ? { eprintln(' fn > |${fkey}|') } @@ -97,8 +91,10 @@ pub fn (mut w Walker) mark_builtin_map_method_as_used(method_name string) { pub fn (mut w Walker) mark_builtin_type_method_as_used(k string, rk string) { if mut cfn := w.all_fns[k] { w.fn_decl(mut cfn) + w.mark_fn_as_used(k) } else if mut cfn := w.all_fns[rk] { w.fn_decl(mut cfn) + w.mark_fn_as_used(rk) } } @@ -486,7 +482,7 @@ fn (mut w Walker) expr(node_ ast.Expr) { } ast.DumpExpr { w.expr(node.expr) - w.features.dump = true + w.uses_dump = true w.mark_by_type(node.expr_type) } ast.SpawnExpr { @@ -512,13 +508,10 @@ fn (mut w Walker) expr(node_ ast.Expr) { w.expr(node.call_expr) } ast.IndexExpr { - if !w.uses_index && !w.is_direct_array_access { - w.uses_index = true - } w.expr(node.left) w.expr(node.index) if node.or_expr.kind == .block { - w.uses_check_index = true + w.uses_guard = true } w.mark_by_type(node.typ) w.or_block(node.or_expr) @@ -536,22 +529,17 @@ fn (mut w Walker) expr(node_ ast.Expr) { w.mark_by_sym(w.table.sym(sym.info.value_type)) w.features.used_maps++ } else if sym.info is ast.Array { - if !w.is_direct_array_access || w.features.auto_str_arr { - if node.is_setter { - w.mark_builtin_array_method_as_used('set') - } else { - w.mark_builtin_array_method_as_used('get') - } + if node.is_setter { + w.mark_builtin_array_method_as_used('set') + } else { + w.mark_builtin_array_method_as_used('get') } w.mark_by_sym(w.table.sym(sym.info.elem_type)) - } else if sym.info is ast.ArrayFixed { - w.uses_fixed_arr_int = true } else if sym.kind == .string { if node.index is ast.RangeExpr { w.mark_builtin_array_method_as_used('slice') w.features.range_index = true } - w.uses_str_index = true } else if sym.info is ast.Struct { w.mark_by_sym(sym) } else if sym.info is ast.SumType { @@ -595,9 +583,6 @@ fn (mut w Walker) expr(node_ ast.Expr) { if !w.uses_eq && node.op in [.eq, .ne] { w.uses_eq = true } - if !w.uses_append && node.op == .left_shift { - w.uses_append = true - } } ast.IfGuardExpr { w.expr(node.expr) @@ -829,25 +814,18 @@ pub fn (mut w Walker) fn_decl(mut node ast.FnDecl) { if node.no_body { return } - if node.is_method { - w.mark_by_type(node.receiver.typ) - } - last_is_direct_array_access := w.is_direct_array_access - w.is_direct_array_access = node.is_direct_arr || w.pref.no_bounds_checking - defer { - w.is_direct_array_access = last_is_direct_array_access - } if w.trace_enabled { w.level++ - defer { - w.level-- - } + defer { w.level-- } receiver_name := if node.is_method && node.receiver.typ != 0 { w.table.type_to_str(node.receiver.typ) + '.' } else { '' } - eprintln('>>>${' '.repeat(w.level)}${receiver_name}${node.name} [${@FN}]') + eprintln('>>>${' '.repeat(w.level)}${receiver_name}${node.name} [decl]') + } + if node.is_method { + w.mark_by_type(node.receiver.typ) } w.mark_fn_ret_and_params(node.return_type, node.params) w.mark_fn_as_used(fkey) @@ -958,22 +936,17 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { stmt := w.all_fns[fn_name] or { return } if !stmt.should_be_skipped && stmt.name == node.name { if !node.is_method || receiver_typ == stmt.receiver.typ { - last_is_direct_array_access := w.is_direct_array_access - w.is_direct_array_access = stmt.is_direct_arr || w.pref.no_bounds_checking - defer { - w.is_direct_array_access = last_is_direct_array_access - } if w.trace_enabled { w.level++ defer { w.level-- } - receiver_name := if stmt.is_method && stmt.receiver.typ != 0 { - w.table.type_to_str(stmt.receiver.typ) + '.' + receiver_name := if node.receiver_type != 0 { + w.table.type_to_str(node.receiver_type) + '.' } else { '' } - eprintln('>>>${' '.repeat(w.level)}${receiver_name}${node.name} [${@FN}]') + eprintln('>>>${' '.repeat(w.level)}${receiver_name}${node.name} [call]') } w.mark_fn_ret_and_params(stmt.return_type, stmt.params) w.stmts(stmt.stmts) @@ -991,22 +964,17 @@ pub fn (mut w Walker) fn_by_name(fn_name string) { return } stmt := w.all_fns[fn_name] or { return } - last_is_direct_array_access := w.is_direct_array_access - w.is_direct_array_access = stmt.is_direct_arr || w.pref.no_bounds_checking - defer { - w.is_direct_array_access = last_is_direct_array_access - } if w.trace_enabled { w.level++ defer { w.level-- } - receiver_name := if stmt.is_method && stmt.receiver.typ != 0 { - w.table.type_to_str(stmt.receiver.typ) + '.' + receiver_name := if fn_name.contains('.') && fn_name.all_before_last('.').int() > 0 { + w.table.type_to_str(fn_name.all_before_last('.').int()) + '.' } else { '' } - eprintln('>>>${' '.repeat(w.level)}${receiver_name}${stmt.name} [${@FN}]') + eprintln('>>>${' '.repeat(w.level)}${receiver_name}${fn_name.all_after_last('.')} [by_name]') } w.mark_fn_as_used(fn_name) w.mark_fn_ret_and_params(stmt.return_type, stmt.params) @@ -1233,6 +1201,14 @@ fn (mut w Walker) remove_unused_fn_generic_types() { } } +fn (mut w Walker) remove_unused_dump_type() { + for typ, _ in w.table.dumps { + if ast.Type(u32(typ)).idx() !in w.used_syms { + w.table.dumps.delete(typ) + } + } +} + fn (mut w Walker) mark_resource_dependencies() { if w.trace_enabled { eprintln('>>>>>>>>>> DEPS USAGE') @@ -1298,16 +1274,12 @@ fn (mut w Walker) mark_resource_dependencies() { if w.uses_mem_align { w.fn_by_name('memdup_align') } - if w.uses_guard || w.uses_check_index { + if w.uses_guard { w.fn_by_name('error') } - if w.features.dump { + if w.uses_dump { w.fn_by_name('eprint') w.fn_by_name('eprintln') - builderptr_idx := int(w.table.find_type('strings.Builder').ref()).str() - w.fn_by_name(builderptr_idx + '.str') - w.fn_by_name(builderptr_idx + '.free') - w.fn_by_name(builderptr_idx + '.write_rune') } if w.uses_spawn { w.fn_by_name('malloc') @@ -1322,33 +1294,6 @@ fn (mut w Walker) mark_resource_dependencies() { if w.uses_arr_void { w.mark_by_type(w.table.find_or_register_array(ast.voidptr_type)) } - if w.features.auto_str || w.uses_dump { - w.fn_by_name(ast.string_type_idx.str() + '.repeat') - w.fn_by_name('tos3') - } - if w.uses_append { - ref_array_idx_str := int(ast.array_type.ref()).str() - w.fn_by_name(ref_array_idx_str + '.push') - w.fn_by_name(ref_array_idx_str + '.push_many_noscan') - w.fn_by_name(ref_array_idx_str + '.push_noscan') - } - if w.uses_index || w.pref.is_shared { - array_idx_str := ast.array_type_idx.str() - w.fn_by_name(array_idx_str + '.slice') - w.fn_by_name(array_idx_str + '.get') - if w.uses_guard || w.uses_check_index { - w.fn_by_name(array_idx_str + '.get_with_check') - } - } - if w.uses_str_index { - string_idx_str := ast.string_type_idx.str() - w.fn_by_name(string_idx_str + '.at') - w.fn_by_name(string_idx_str + '.at_with_check') - w.fn_by_name(string_idx_str + '.substr') - } - if w.uses_fixed_arr_int { - w.fn_by_name('v_fixed_index') - } for typ, _ in w.table.used_features.print_types { w.mark_by_type(typ) } @@ -1371,8 +1316,6 @@ fn (mut w Walker) mark_resource_dependencies() { mut map_fns := map[string]ast.FnDecl{} has_str_call := w.uses_interp || w.uses_asserts || w.uses_str.len > 0 || w.features.print_types.len > 0 - - orm_impls := w.table.iface_types['orm.Connection'] or { []ast.Type{} } for k, mut func in w.all_fns { if has_str_call && k.ends_with('.str') { if func.receiver.typ.idx() in w.used_syms { @@ -1411,28 +1354,9 @@ fn (mut w Walker) mark_resource_dependencies() { method_receiver_typename := w.table.type_to_str(func.receiver.typ) if method_receiver_typename in ['&map', '&mapnode', '&SortedMap', '&DenseArray'] { map_fns[k] = func - continue } } else if k.starts_with('map_') { map_fns[k] = func - continue - } - if orm_impls.len > 0 && k.starts_with('orm.') { - w.fn_by_name(k) - continue - } - } - // handle ORM drivers: - if orm_impls.len > 0 { - for orm_type in orm_impls { - typ := int(orm_type).str() - w.fn_by_name(typ + '.select') - w.fn_by_name(typ + '.insert') - w.fn_by_name(typ + '.update') - w.fn_by_name(typ + '.delete') - w.fn_by_name(typ + '.create') - w.fn_by_name(typ + '.drop') - w.fn_by_name(typ + '.last_id') } } if w.features.used_maps > 0 { @@ -1484,20 +1408,20 @@ pub fn (mut w Walker) finalize(include_panic_deps bool) { w.mark_by_sym_name('VAssertMetaInfo') } if w.used_panic > 0 { - w.fn_by_name('panic_option_not_set') - w.fn_by_name('panic_result_not_set') + w.mark_fn_as_used('panic_option_not_set') + w.mark_fn_as_used('panic_result_not_set') } if w.used_none > 0 || w.table.used_features.auto_str { - w.fn_by_name('_option_none') + w.mark_fn_as_used('_option_none') w.mark_by_sym_name('_option') } if w.used_option > 0 { - w.fn_by_name('_option_clone') - w.fn_by_name('_option_ok') + w.mark_fn_as_used('_option_clone') + w.mark_fn_as_used('_option_ok') w.mark_by_sym_name('_option') } if w.used_result > 0 { - w.fn_by_name('_result_ok') + w.mark_fn_as_used('_result_ok') w.mark_by_sym_name('_result') } if (w.used_option + w.used_result + w.used_none) > 0 { @@ -1506,7 +1430,7 @@ pub fn (mut w Walker) finalize(include_panic_deps bool) { if include_panic_deps || w.uses_external_type || w.uses_asserts || w.uses_debugger || w.uses_interp { if w.trace_enabled { - eprintln('>>>>> PANIC DEPS ${include_panic_deps} | external_type=${w.uses_external_type} | asserts=${w.uses_asserts} | dbg=${w.uses_debugger} interp=${w.uses_interp}') + eprintln('>>>>> PANIC DEPS ${include_panic_deps} | external_type=${w.uses_external_type} | asserts=${w.uses_asserts} | dbg=${w.uses_debugger}') } ref_array_idx_str := int(ast.array_type.ref()).str() string_idx_str := ast.string_type_idx.str() @@ -1526,6 +1450,7 @@ pub fn (mut w Walker) finalize(include_panic_deps bool) { // remove unused symbols w.remove_unused_fn_generic_types() + w.remove_unused_dump_type() if w.trace_enabled { syms := w.used_syms.keys().map(w.table.type_to_str(it))