markused: fix interface fields and chan usage (fix #24961) (#24962)

This commit is contained in:
Felipe Pena 2025-07-24 12:25:41 -03:00 committed by GitHub
parent 05479f3bd9
commit a309593f56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 63 additions and 14 deletions

View File

@ -1185,6 +1185,9 @@ pub fn (mut g Gen) write_typeof_functions() {
if inter_info.is_generic { if inter_info.is_generic {
continue continue
} }
if g.pref.skip_unused && sym.idx !in g.table.used_features.used_syms {
continue
}
g.definitions.writeln('${g.static_non_parallel}char * v_typeof_interface_${sym.cname}(int sidx);') g.definitions.writeln('${g.static_non_parallel}char * v_typeof_interface_${sym.cname}(int sidx);')
if g.pref.parallel_cc { if g.pref.parallel_cc {
g.extern_out.writeln('extern char * v_typeof_interface_${sym.cname}(int sidx);') 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() {
if opt_el_type in done { if opt_el_type in done {
continue continue
} }
if g.pref.skip_unused {
if sym := g.table.find_sym(opt_el_type) {
if sym.idx !in g.table.used_features.used_syms {
continue
}
}
}
done << opt_el_type done << opt_el_type
g.channel_definitions.writeln(' g.channel_definitions.writeln('
static inline ${opt_el_type} __Option_${styp}_popval(${styp} ch) { static inline ${opt_el_type} __Option_${styp}_popval(${styp} ch) {
@ -1642,6 +1652,13 @@ fn (mut g Gen) write_chan_push_option_fns() {
if styp in done { if styp in done {
continue continue
} }
if g.pref.skip_unused {
if sym := g.table.find_sym(el_type) {
if sym.idx !in g.table.used_features.used_syms {
continue
}
}
}
done << styp done << styp
g.register_option(ast.void_type.set_flag(.option)) g.register_option(ast.void_type.set_flag(.option))
g.channel_definitions.writeln(' g.channel_definitions.writeln('
@ -1744,10 +1761,14 @@ pub fn (mut g Gen) write_typedef_types() {
} }
.chan { .chan {
if sym.name != 'chan' { if sym.name != 'chan' {
g.type_definitions.writeln('typedef chan ${sym.cname};')
chan_inf := sym.chan_info() chan_inf := sym.chan_info()
chan_elem_type := chan_inf.elem_type chan_elem_type := chan_inf.elem_type
is_fixed_arr := g.table.sym(chan_elem_type).kind == .array_fixed esym := g.table.sym(chan_elem_type)
if g.pref.skip_unused && esym.idx !in g.table.used_features.used_syms {
continue
}
g.type_definitions.writeln('typedef chan ${sym.cname};')
is_fixed_arr := esym.kind == .array_fixed
if !chan_elem_type.has_flag(.generic) { if !chan_elem_type.has_flag(.generic) {
el_stype := if is_fixed_arr { '_v_' } else { '' } + g.styp(chan_elem_type) el_stype := if is_fixed_arr { '_v_' } else { '' } + g.styp(chan_elem_type)
val_arg_pop := if is_fixed_arr { '&val.ret_arr' } else { '&val' } 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) {
} }
} }
for sym in interface_non_generic_syms { for sym in interface_non_generic_syms {
if g.pref.skip_unused && sym.idx !in g.table.used_features.used_syms {
continue
}
g.write_interface_typesymbol_declaration(sym) g.write_interface_typesymbol_declaration(sym)
} }
} }
@ -6444,7 +6468,8 @@ fn (mut g Gen) write_debug_calls_typeof_functions() {
continue continue
} }
inter_info := sym.info as ast.Interface inter_info := sym.info as ast.Interface
if inter_info.is_generic { if inter_info.is_generic
|| (g.pref.skip_unused && sym.idx !in g.table.used_features.used_syms) {
continue continue
} }
g.writeln('\tv_typeof_interface_${sym.cname}(0);') g.writeln('\tv_typeof_interface_${sym.cname}(0);')
@ -6646,6 +6671,9 @@ fn (mut g Gen) write_builtin_types() {
// everything except builtin will get sorted // everything except builtin will get sorted
for builtin_name in ast.builtins { for builtin_name in ast.builtins {
sym := g.table.sym_by_idx(g.table.type_idxs[builtin_name]) sym := g.table.sym_by_idx(g.table.type_idxs[builtin_name])
if g.pref.skip_unused && sym.idx !in g.table.used_features.used_syms {
continue
}
if sym.info is ast.Interface { if sym.info is ast.Interface {
g.write_interface_typedef(sym) g.write_interface_typedef(sym)
if !sym.info.is_generic { if !sym.info.is_generic {
@ -7802,6 +7830,9 @@ fn (mut g Gen) interface_table() string {
if inter_info.is_generic { if inter_info.is_generic {
continue continue
} }
if g.pref.skip_unused && isym.idx !in g.table.used_features.used_syms {
continue
}
// interface_name is for example Speaker // interface_name is for example Speaker
interface_name := isym.cname interface_name := isym.cname
// generate a struct that references interface methods // generate a struct that references interface methods

View File

@ -8,7 +8,7 @@ import v.pref
// mark_used walks the AST, starting at main() and marks all used fns transitively. // mark_used walks the AST, starting at main() and marks all used fns transitively.
pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&ast.File) { pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&ast.File) {
mut all_fns, all_consts, all_globals, all_fields, all_decltypes := all_global_decl(ast_files) mut all_fns, all_consts, all_globals, all_fields, all_decltypes, all_structs := all_global_decl(ast_files)
util.timing_start('MARKUSED') util.timing_start('MARKUSED')
defer { defer {
util.timing_measure('MARKUSED') util.timing_measure('MARKUSED')
@ -447,6 +447,7 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
all_globals: all_globals all_globals: all_globals
all_fields: all_fields all_fields: all_fields
all_decltypes: all_decltypes all_decltypes: all_decltypes
all_structs: all_structs
pref: pref_ pref: pref_
) )
walker.mark_markused_consts() // tagged with `@[markused]` 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
} }
} }
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) { 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) {
util.timing_start(@METHOD) util.timing_start(@METHOD)
defer { defer {
util.timing_measure(@METHOD) util.timing_measure(@METHOD)
@ -596,6 +597,7 @@ fn all_global_decl(ast_files []&ast.File) (map[string]ast.FnDecl, map[string]ast
mut all_globals := map[string]ast.GlobalField{} mut all_globals := map[string]ast.GlobalField{}
mut all_fields := map[string]ast.StructField{} mut all_fields := map[string]ast.StructField{}
mut all_decltypes := map[string]ast.Type{} mut all_decltypes := map[string]ast.Type{}
mut all_structs := map[string]ast.StructDecl{}
for i in 0 .. ast_files.len { for i in 0 .. ast_files.len {
for node in ast_files[i].stmts { for node in ast_files[i].stmts {
match node { match node {
@ -622,6 +624,7 @@ fn all_global_decl(ast_files []&ast.File) (map[string]ast.FnDecl, map[string]ast
sfkey := sfield.sfkey() sfkey := sfield.sfkey()
all_fields[sfkey] = sfield all_fields[sfkey] = sfield
} }
all_structs[node.name] = node
} }
ast.TypeDecl { ast.TypeDecl {
all_decltypes[node.name] = node.typ 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
} }
} }
} }
return all_fns, all_consts, all_globals, all_fields, all_decltypes return all_fns, all_consts, all_globals, all_fields, all_decltypes, all_structs
} }
fn mark_all_methods_used(mut table ast.Table, mut all_fn_root_names []string, typ ast.Type) { fn mark_all_methods_used(mut table ast.Table, mut all_fn_root_names []string, typ ast.Type) {

View File

@ -30,6 +30,7 @@ mut:
all_globals map[string]ast.GlobalField all_globals map[string]ast.GlobalField
all_fields map[string]ast.StructField all_fields map[string]ast.StructField
all_decltypes map[string]ast.Type all_decltypes map[string]ast.Type
all_structs map[string]ast.StructDecl
} }
pub fn Walker.new(params Walker) &Walker { pub fn Walker.new(params Walker) &Walker {
@ -301,6 +302,9 @@ pub fn (mut w Walker) stmt(node_ ast.Stmt) {
} }
} }
ast.StructDecl { ast.StructDecl {
for typ in node.implements_types {
w.mark_by_type(typ.typ)
}
w.struct_fields(node.fields) w.struct_fields(node.fields)
} }
ast.DeferStmt { ast.DeferStmt {
@ -921,8 +925,7 @@ pub fn (mut w Walker) mark_by_type(typ ast.Type) {
if typ.has_flag(.generic) { if typ.has_flag(.generic) {
return return
} }
sym := w.table.sym(typ) w.mark_by_sym(w.table.sym(typ))
w.mark_by_sym(sym)
} }
pub fn (mut w Walker) mark_by_sym(isym ast.TypeSymbol) { 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) {
} }
} }
match fsym.info { match fsym.info {
ast.Struct, ast.SumType, ast.FnType, ast.Alias, ast.Chan {
w.mark_by_sym(fsym)
}
ast.Array, ast.ArrayFixed { ast.Array, ast.ArrayFixed {
w.features.used_arrays++ w.features.used_arrays++
w.mark_by_type(ifield.typ) w.mark_by_sym(fsym)
} }
ast.Map { ast.Map {
w.features.used_maps++ w.features.used_maps++
w.mark_by_type(ifield.typ) w.mark_by_sym(fsym)
}
else {
w.mark_by_sym(fsym)
} }
else {}
} }
} }
} }
for embed in isym.info.embeds { for embed in isym.info.embeds {
w.mark_by_type(embed) w.mark_by_type(embed)
} }
if decl := w.all_structs[isym.name] {
for iface_typ in decl.implements_types {
w.mark_by_type(iface_typ.typ)
}
}
} }
ast.ArrayFixed, ast.Array { ast.ArrayFixed, ast.Array {
w.mark_by_type(isym.info.elem_type) w.mark_by_type(isym.info.elem_type)
@ -1024,6 +1031,9 @@ pub fn (mut w Walker) mark_by_sym(isym ast.TypeSymbol) {
if isym.info.parent_type != 0 { if isym.info.parent_type != 0 {
w.mark_by_type(isym.info.parent_type) w.mark_by_type(isym.info.parent_type)
} }
for field in isym.info.fields {
w.mark_by_type(field.typ)
}
for method in isym.methods { for method in isym.methods {
if method.receiver_type != 0 { if method.receiver_type != 0 {
w.mark_by_type(method.receiver_type) w.mark_by_type(method.receiver_type)

View File

@ -0,0 +1,5 @@
struct Foo {}
interface Bar {
a Foo
}