Skip to content

Commit a309593

Browse files
authored
markused: fix interface fields and chan usage (fix #24961) (#24962)
1 parent 05479f3 commit a309593

6 files changed

Lines changed: 63 additions & 14 deletions

File tree

‎vlib/v/gen/c/cgen.v‎

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,9 @@ pub fn (mut g Gen) write_typeof_functions() {
11851185
if inter_info.is_generic {
11861186
continue
11871187
}
1188+
if g.pref.skip_unused && sym.idx !in g.table.used_features.used_syms {
1189+
continue
1190+
}
11881191
g.definitions.writeln('${g.static_non_parallel}char * v_typeof_interface_${sym.cname}(int sidx);')
11891192
if g.pref.parallel_cc {
11901193
g.extern_out.writeln('extern char * v_typeof_interface_${sym.cname}(int sidx);')
@@ -1620,6 +1623,13 @@ fn (mut g Gen) write_chan_pop_option_fns() {
16201623
if opt_el_type in done {
16211624
continue
16221625
}
1626+
if g.pref.skip_unused {
1627+
if sym := g.table.find_sym(opt_el_type) {
1628+
if sym.idx !in g.table.used_features.used_syms {
1629+
continue
1630+
}
1631+
}
1632+
}
16231633
done << opt_el_type
16241634
g.channel_definitions.writeln('
16251635
static inline ${opt_el_type} __Option_${styp}_popval(${styp} ch) {
@@ -1642,6 +1652,13 @@ fn (mut g Gen) write_chan_push_option_fns() {
16421652
if styp in done {
16431653
continue
16441654
}
1655+
if g.pref.skip_unused {
1656+
if sym := g.table.find_sym(el_type) {
1657+
if sym.idx !in g.table.used_features.used_syms {
1658+
continue
1659+
}
1660+
}
1661+
}
16451662
done << styp
16461663
g.register_option(ast.void_type.set_flag(.option))
16471664
g.channel_definitions.writeln('
@@ -1744,10 +1761,14 @@ pub fn (mut g Gen) write_typedef_types() {
17441761
}
17451762
.chan {
17461763
if sym.name != 'chan' {
1747-
g.type_definitions.writeln('typedef chan ${sym.cname};')
17481764
chan_inf := sym.chan_info()
17491765
chan_elem_type := chan_inf.elem_type
1750-
is_fixed_arr := g.table.sym(chan_elem_type).kind == .array_fixed
1766+
esym := g.table.sym(chan_elem_type)
1767+
if g.pref.skip_unused && esym.idx !in g.table.used_features.used_syms {
1768+
continue
1769+
}
1770+
g.type_definitions.writeln('typedef chan ${sym.cname};')
1771+
is_fixed_arr := esym.kind == .array_fixed
17511772
if !chan_elem_type.has_flag(.generic) {
17521773
el_stype := if is_fixed_arr { '_v_' } else { '' } + g.styp(chan_elem_type)
17531774
val_arg_pop := if is_fixed_arr { '&val.ret_arr' } else { '&val' }
@@ -1798,6 +1819,9 @@ static inline void __${sym.cname}_pushval(${sym.cname} ch, ${push_arg} val) {
17981819
}
17991820
}
18001821
for sym in interface_non_generic_syms {
1822+
if g.pref.skip_unused && sym.idx !in g.table.used_features.used_syms {
1823+
continue
1824+
}
18011825
g.write_interface_typesymbol_declaration(sym)
18021826
}
18031827
}
@@ -6444,7 +6468,8 @@ fn (mut g Gen) write_debug_calls_typeof_functions() {
64446468
continue
64456469
}
64466470
inter_info := sym.info as ast.Interface
6447-
if inter_info.is_generic {
6471+
if inter_info.is_generic
6472+
|| (g.pref.skip_unused && sym.idx !in g.table.used_features.used_syms) {
64486473
continue
64496474
}
64506475
g.writeln('\tv_typeof_interface_${sym.cname}(0);')
@@ -6646,6 +6671,9 @@ fn (mut g Gen) write_builtin_types() {
66466671
// everything except builtin will get sorted
66476672
for builtin_name in ast.builtins {
66486673
sym := g.table.sym_by_idx(g.table.type_idxs[builtin_name])
6674+
if g.pref.skip_unused && sym.idx !in g.table.used_features.used_syms {
6675+
continue
6676+
}
66496677
if sym.info is ast.Interface {
66506678
g.write_interface_typedef(sym)
66516679
if !sym.info.is_generic {
@@ -7802,6 +7830,9 @@ fn (mut g Gen) interface_table() string {
78027830
if inter_info.is_generic {
78037831
continue
78047832
}
7833+
if g.pref.skip_unused && isym.idx !in g.table.used_features.used_syms {
7834+
continue
7835+
}
78057836
// interface_name is for example Speaker
78067837
interface_name := isym.cname
78077838
// generate a struct that references interface methods

‎vlib/v/markused/markused.v‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import v.pref
88

99
// mark_used walks the AST, starting at main() and marks all used fns transitively.
1010
pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&ast.File) {
11-
mut all_fns, all_consts, all_globals, all_fields, all_decltypes := all_global_decl(ast_files)
11+
mut all_fns, all_consts, all_globals, all_fields, all_decltypes, all_structs := all_global_decl(ast_files)
1212
util.timing_start('MARKUSED')
1313
defer {
1414
util.timing_measure('MARKUSED')
@@ -447,6 +447,7 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
447447
all_globals: all_globals
448448
all_fields: all_fields
449449
all_decltypes: all_decltypes
450+
all_structs: all_structs
450451
pref: pref_
451452
)
452453
walker.mark_markused_consts() // tagged with `@[markused]`
@@ -586,7 +587,7 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
586587
}
587588
}
588589

589-
fn all_global_decl(ast_files []&ast.File) (map[string]ast.FnDecl, map[string]ast.ConstField, map[string]ast.GlobalField, map[string]ast.StructField, map[string]ast.Type) {
590+
fn all_global_decl(ast_files []&ast.File) (map[string]ast.FnDecl, map[string]ast.ConstField, map[string]ast.GlobalField, map[string]ast.StructField, map[string]ast.Type, map[string]ast.StructDecl) {
590591
util.timing_start(@METHOD)
591592
defer {
592593
util.timing_measure(@METHOD)
@@ -596,6 +597,7 @@ fn all_global_decl(ast_files []&ast.File) (map[string]ast.FnDecl, map[string]ast
596597
mut all_globals := map[string]ast.GlobalField{}
597598
mut all_fields := map[string]ast.StructField{}
598599
mut all_decltypes := map[string]ast.Type{}
600+
mut all_structs := map[string]ast.StructDecl{}
599601
for i in 0 .. ast_files.len {
600602
for node in ast_files[i].stmts {
601603
match node {
@@ -622,6 +624,7 @@ fn all_global_decl(ast_files []&ast.File) (map[string]ast.FnDecl, map[string]ast
622624
sfkey := sfield.sfkey()
623625
all_fields[sfkey] = sfield
624626
}
627+
all_structs[node.name] = node
625628
}
626629
ast.TypeDecl {
627630
all_decltypes[node.name] = node.typ
@@ -630,7 +633,7 @@ fn all_global_decl(ast_files []&ast.File) (map[string]ast.FnDecl, map[string]ast
630633
}
631634
}
632635
}
633-
return all_fns, all_consts, all_globals, all_fields, all_decltypes
636+
return all_fns, all_consts, all_globals, all_fields, all_decltypes, all_structs
634637
}
635638

636639
fn mark_all_methods_used(mut table ast.Table, mut all_fn_root_names []string, typ ast.Type) {

‎vlib/v/markused/walker.v‎

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mut:
3030
all_globals map[string]ast.GlobalField
3131
all_fields map[string]ast.StructField
3232
all_decltypes map[string]ast.Type
33+
all_structs map[string]ast.StructDecl
3334
}
3435

3536
pub fn Walker.new(params Walker) &Walker {
@@ -301,6 +302,9 @@ pub fn (mut w Walker) stmt(node_ ast.Stmt) {
301302
}
302303
}
303304
ast.StructDecl {
305+
for typ in node.implements_types {
306+
w.mark_by_type(typ.typ)
307+
}
304308
w.struct_fields(node.fields)
305309
}
306310
ast.DeferStmt {
@@ -921,8 +925,7 @@ pub fn (mut w Walker) mark_by_type(typ ast.Type) {
921925
if typ.has_flag(.generic) {
922926
return
923927
}
924-
sym := w.table.sym(typ)
925-
w.mark_by_sym(sym)
928+
w.mark_by_sym(w.table.sym(typ))
926929
}
927930

928931
pub fn (mut w Walker) mark_by_sym(isym ast.TypeSymbol) {
@@ -945,24 +948,28 @@ pub fn (mut w Walker) mark_by_sym(isym ast.TypeSymbol) {
945948
}
946949
}
947950
match fsym.info {
948-
ast.Struct, ast.SumType, ast.FnType, ast.Alias, ast.Chan {
949-
w.mark_by_sym(fsym)
950-
}
951951
ast.Array, ast.ArrayFixed {
952952
w.features.used_arrays++
953-
w.mark_by_type(ifield.typ)
953+
w.mark_by_sym(fsym)
954954
}
955955
ast.Map {
956956
w.features.used_maps++
957-
w.mark_by_type(ifield.typ)
957+
w.mark_by_sym(fsym)
958+
}
959+
else {
960+
w.mark_by_sym(fsym)
958961
}
959-
else {}
960962
}
961963
}
962964
}
963965
for embed in isym.info.embeds {
964966
w.mark_by_type(embed)
965967
}
968+
if decl := w.all_structs[isym.name] {
969+
for iface_typ in decl.implements_types {
970+
w.mark_by_type(iface_typ.typ)
971+
}
972+
}
966973
}
967974
ast.ArrayFixed, ast.Array {
968975
w.mark_by_type(isym.info.elem_type)
@@ -1024,6 +1031,9 @@ pub fn (mut w Walker) mark_by_sym(isym ast.TypeSymbol) {
10241031
if isym.info.parent_type != 0 {
10251032
w.mark_by_type(isym.info.parent_type)
10261033
}
1034+
for field in isym.info.fields {
1035+
w.mark_by_type(field.typ)
1036+
}
10271037
for method in isym.methods {
10281038
if method.receiver_type != 0 {
10291039
w.mark_by_type(method.receiver_type)

‎vlib/v/tests/skip_unused/interface_unused.run.out‎

Whitespace-only changes.

‎vlib/v/tests/skip_unused/interface_unused.skip_unused.run.out‎

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
struct Foo {}
2+
3+
interface Bar {
4+
a Foo
5+
}

0 commit comments

Comments
 (0)