Skip to content

Commit 1b9f15d

Browse files
authored
checker: cleanup used_features logic (#23502)
1 parent 496451e commit 1b9f15d

File tree

9 files changed

+223
-168
lines changed

9 files changed

+223
-168
lines changed

vlib/v/ast/table.v

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import v.util
1010
@[heap; minify]
1111
pub struct UsedFeatures {
1212
pub mut:
13-
interfaces bool // interface
1413
dump bool // dump()
1514
index bool // string[0]
1615
range_index bool // string[0..1]

vlib/v/checker/checker.v

Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,9 +1392,8 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast.
13921392
}
13931393

13941394
fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return_type ast.Type, expr ast.Expr) {
1395-
if c.pref.skip_unused && !c.is_builtin_mod && node.kind != .absent && c.mod != 'strings' {
1396-
c.table.used_features.option_or_result = true
1397-
}
1395+
c.markused_option_or_result(!c.is_builtin_mod && node.kind != .absent && c.mod != 'strings')
1396+
13981397
if node.kind == .propagate_option {
13991398
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.option)
14001399
&& !c.table.cur_fn.is_main && !c.table.cur_fn.is_test && !c.inside_const {
@@ -1794,16 +1793,12 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
17941793
c.check_or_expr(node.or_block, unwrapped_typ, c.expected_or_type, node)
17951794
c.expected_or_type = ast.void_type
17961795
}
1797-
if c.pref.skip_unused && node.or_block.kind != .absent
1798-
&& !c.table.used_features.option_or_result {
1799-
c.table.used_features.option_or_result = true
1800-
}
1796+
c.markused_option_or_result(node.or_block.kind != .absent
1797+
&& !c.table.used_features.option_or_result)
18011798
return field.typ
18021799
}
18031800
if mut method := c.table.sym(c.unwrap_generic(typ)).find_method_with_generic_parent(field_name) {
1804-
if c.pref.skip_unused && typ.has_flag(.generic) {
1805-
c.table.used_features.comptime_calls['${int(method.params[0].typ)}.${field_name}'] = true
1806-
}
1801+
c.markused_comptime_call(typ.has_flag(.generic), '${int(method.params[0].typ)}.${field_name}')
18071802
if c.expected_type != 0 && c.expected_type != ast.none_type {
18081803
fn_type := ast.new_type(c.table.find_or_register_fn_type(method, false, true))
18091804
// if the expected type includes the receiver, don't hide it behind a closure
@@ -2383,15 +2378,7 @@ fn (mut c Checker) assert_stmt(mut node ast.AssertStmt) {
23832378
cur_exp_typ := c.expected_type
23842379
c.expected_type = ast.bool_type
23852380
assert_type := c.check_expr_option_or_result_call(node.expr, c.expr(mut node.expr))
2386-
if c.pref.skip_unused && !c.table.used_features.auto_str && !c.is_builtin_mod
2387-
&& mut node.expr is ast.InfixExpr {
2388-
if !c.table.sym(c.unwrap_generic(node.expr.left_type)).has_method('str') {
2389-
c.table.used_features.auto_str = true
2390-
}
2391-
if !c.table.sym(c.unwrap_generic(node.expr.right_type)).has_method('str') {
2392-
c.table.used_features.auto_str = true
2393-
}
2394-
}
2381+
c.markused_assertstmt_auto_str(mut node)
23952382
if assert_type != ast.bool_type_idx {
23962383
atype_name := c.table.sym(assert_type).name
23972384
c.error('assert can be used only with `bool` expressions, but found `${atype_name}` instead',
@@ -3051,17 +3038,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
30513038
c.table.used_features.dump = true
30523039
c.expected_type = ast.string_type
30533040
node.expr_type = c.expr(mut node.expr)
3054-
if c.pref.skip_unused && !c.is_builtin_mod {
3055-
if !c.table.sym(c.unwrap_generic(node.expr_type)).has_method('str') {
3056-
c.table.used_features.auto_str = true
3057-
if node.expr_type.is_ptr() {
3058-
c.table.used_features.auto_str_ptr = true
3059-
}
3060-
} else {
3061-
c.table.used_features.print_types[node.expr_type.idx()] = true
3062-
}
3063-
c.table.used_features.print_types[ast.int_type_idx] = true
3064-
}
3041+
c.markused_dumpexpr(mut node)
30653042
if c.comptime.inside_comptime_for && mut node.expr is ast.Ident {
30663043
if node.expr.ct_expr {
30673044
node.expr_type = c.type_resolver.get_type(node.expr as ast.Ident)
@@ -3284,10 +3261,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
32843261
ast.StructInit {
32853262
if node.unresolved {
32863263
mut expr_ := c.table.resolve_init(node, c.unwrap_generic(node.typ))
3287-
if c.pref.skip_unused && c.table.used_features.used_maps == 0
3288-
&& expr_ is ast.MapInit {
3289-
c.table.used_features.used_maps++
3290-
}
3264+
c.markused_used_maps(c.table.used_features.used_maps == 0 && expr_ is ast.MapInit)
32913265
return c.expr(mut expr_)
32923266
}
32933267
mut inited_fields := []string{}
@@ -3374,16 +3348,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
33743348
to_type
33753349
}
33763350
final_to_is_ptr := to_type.is_ptr() || final_to_type.is_ptr()
3377-
if c.pref.skip_unused && !c.is_builtin_mod {
3378-
if c.table.used_features.used_maps == 0 && mut final_to_sym.info is ast.SumType {
3379-
if final_to_sym.info.variants.any(c.table.final_sym(it).kind == .map) {
3380-
c.table.used_features.used_maps++
3381-
}
3382-
}
3383-
if c.mod !in ['strings', 'math.bits'] && to_type.is_ptr() {
3384-
c.table.used_features.cast_ptr = true
3385-
}
3386-
}
3351+
c.markused_castexpr(mut node, to_type, mut final_to_sym)
33873352
if to_type.has_flag(.result) {
33883353
c.error('casting to Result type is forbidden', node.pos)
33893354
}
@@ -4003,9 +3968,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
40033968
c.error('`mut` is not allowed with `=` (use `:=` to declare a variable)',
40043969
node.pos)
40053970
}
4006-
if c.pref.skip_unused && !c.is_builtin_mod && node.language == .v && node.name.contains('.') {
4007-
c.table.used_features.external_types = true
4008-
}
3971+
c.markused_external_type(!c.is_builtin_mod && node.language == .v && node.name.contains('.'))
40093972
if mut obj := node.scope.find(node.name) {
40103973
match mut obj {
40113974
ast.GlobalField {

vlib/v/checker/comptime.v

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -133,32 +133,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
133133
// check each arg expression
134134
node.args[i].typ = c.expr(mut arg.expr)
135135
}
136-
if c.pref.skip_unused {
137-
c.table.used_features.comptime_calls['${int(c.unwrap_generic(c.comptime.comptime_for_method.receiver_type))}.${c.comptime.comptime_for_method.name}'] = true
138-
if c.inside_anon_fn {
139-
// $method passed to anon fn, mark all methods as used
140-
sym := c.table.sym(c.unwrap_generic(node.left_type))
141-
for m in sym.get_methods() {
142-
c.table.used_features.comptime_calls['${int(c.unwrap_generic(m.receiver_type))}.${m.name}'] = true
143-
if node.args.len > 0 && m.params.len > 0 {
144-
last_param := m.params.last().typ
145-
if (last_param.is_int() || last_param.is_bool())
146-
&& c.table.final_sym(node.args.last().typ).kind == .array {
147-
c.table.used_features.comptime_calls['${ast.string_type_idx}.${c.table.type_to_str(m.params.last().typ)}'] = true
148-
}
149-
}
150-
}
151-
} else {
152-
m := c.comptime.comptime_for_method
153-
if node.args.len > 0 && m.params.len > 0 {
154-
last_param := m.params.last().typ
155-
if (last_param.is_int() || last_param.is_bool())
156-
&& c.table.final_sym(node.args.last().typ).kind == .array {
157-
c.table.used_features.comptime_calls['${ast.string_type_idx}.${c.table.type_to_str(m.params.last().typ)}'] = true
158-
}
159-
}
160-
}
161-
}
136+
c.markused_comptimecall(mut node)
162137
c.stmts_ending_with_expression(mut node.or_block.stmts, c.expected_or_type)
163138
return c.type_resolver.get_type(node)
164139
}
@@ -223,9 +198,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
223198
c.error('could not find method `${method_name}`', node.method_pos)
224199
return ast.void_type
225200
}
226-
if c.pref.skip_unused {
227-
c.table.used_features.comptime_calls['${int(left_type)}.${method_name}'] = true
228-
}
201+
c.markused_comptime_call(true, '${int(left_type)}.${method_name}')
229202
node.result_type = f.return_type
230203
return f.return_type
231204
}
@@ -312,19 +285,7 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
312285
unwrapped_expr_type := c.unwrap_generic(field.typ)
313286
tsym := c.table.sym(unwrapped_expr_type)
314287
c.table.dumps[int(unwrapped_expr_type.clear_flags(.option, .result, .atomic_f))] = tsym.cname
315-
if c.pref.skip_unused {
316-
c.table.used_features.dump = true
317-
if c.table.used_features.used_maps == 0 {
318-
final_sym := c.table.final_sym(unwrapped_expr_type)
319-
if final_sym.info is ast.Map {
320-
c.table.used_features.used_maps++
321-
} else if final_sym.info is ast.SumType {
322-
if final_sym.info.variants.any(c.table.final_sym(it).kind == .map) {
323-
c.table.used_features.used_maps++
324-
}
325-
}
326-
}
327-
}
288+
c.markused_comptimefor(mut node, unwrapped_expr_type)
328289
if tsym.kind == .array_fixed {
329290
info := tsym.info as ast.ArrayFixed
330291
if !info.is_fn_ret {

vlib/v/checker/containers.v

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
6565
}
6666
}
6767
ast.Map {
68-
if c.pref.skip_unused && !c.is_builtin_mod {
69-
c.table.used_features.arr_map = true
70-
}
68+
c.markused_array_method(!c.is_builtin_mod, 'map')
7169
}
7270
else {}
7371
}

vlib/v/checker/fn.v

Lines changed: 8 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -756,22 +756,10 @@ fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
756756
c.check_or_expr(node.or_block, typ, c.expected_or_type, node)
757757
c.inside_or_block_value = old_inside_or_block_value
758758
} else if node.or_block.kind == .propagate_option || node.or_block.kind == .propagate_result {
759-
if c.pref.skip_unused && !c.is_builtin_mod && c.mod != 'strings' {
760-
c.table.used_features.option_or_result = true
761-
}
759+
c.markused_option_or_result(!c.is_builtin_mod && c.mod != 'strings')
762760
}
763761
c.expected_or_type = old_expected_or_type
764-
if c.pref.skip_unused && !c.is_builtin_mod && c.mod == 'main'
765-
&& !c.table.used_features.external_types {
766-
if node.is_method {
767-
if c.table.sym(node.left_type).is_builtin() {
768-
c.table.used_features.external_types = true
769-
}
770-
} else if node.name.contains('.') {
771-
c.table.used_features.external_types = true
772-
}
773-
}
774-
762+
c.markused_call_expr(mut node)
775763
if !c.inside_const && c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.is_main
776764
&& !c.table.cur_fn.is_test {
777765
// TODO: use just `if node.or_block.kind == .propagate_result && !c.table.cur_fn.return_type.has_flag(.result) {` after the deprecation for ?!Type
@@ -1422,20 +1410,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
14221410
if node.args.len > 0 && fn_name in print_everything_fns {
14231411
node.args[0].ct_expr = c.comptime.is_comptime(node.args[0].expr)
14241412
c.builtin_args(mut node, fn_name, func)
1425-
if c.pref.skip_unused && !c.is_builtin_mod && c.mod != 'math.bits'
1426-
&& node.args[0].expr !is ast.StringLiteral {
1427-
if !c.table.sym(c.unwrap_generic(node.args[0].typ)).has_method('str') {
1428-
c.table.used_features.auto_str = true
1429-
} else {
1430-
if node.args[0].typ.has_option_or_result() {
1431-
c.table.used_features.option_or_result = true
1432-
}
1433-
c.table.used_features.print_types[node.args[0].typ.idx()] = true
1434-
}
1435-
if node.args[0].typ.is_ptr() {
1436-
c.table.used_features.auto_str_ptr = true
1437-
}
1438-
}
1413+
c.markused_fn_call(mut node)
14391414
return func.return_type
14401415
}
14411416
// `return error(err)` -> `return err`
@@ -1980,15 +1955,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
19801955
continue_check = false
19811956
return ast.void_type
19821957
}
1983-
if c.pref.skip_unused {
1984-
if !left_type.has_flag(.generic) && mut left_expr is ast.Ident {
1985-
if left_expr.obj is ast.Var && left_expr.obj.ct_type_var == .smartcast {
1986-
c.table.used_features.comptime_calls['${int(left_type)}.${node.name}'] = true
1987-
}
1988-
} else if left_type.has_flag(.generic) {
1989-
c.table.used_features.comptime_calls['${int(c.unwrap_generic(left_type))}.${node.name}'] = true
1990-
}
1991-
}
1958+
c.markused_method_call(mut node, mut left_expr, left_type)
19921959
c.expected_type = left_type
19931960
mut is_generic := left_type.has_flag(.generic)
19941961
node.left_type = left_type
@@ -2119,9 +2086,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
21192086
if embed_types.len != 0 {
21202087
is_method_from_embed = true
21212088
node.from_embed_types = embed_types
2122-
if c.pref.skip_unused && node.left_type.has_flag(.generic) {
2123-
c.table.used_features.comptime_calls['${int(method.receiver_type)}.${method.name}'] = true
2124-
}
2089+
c.markused_comptime_call(node.left_type.has_flag(.generic), '${int(method.receiver_type)}.${method.name}')
21252090
}
21262091
}
21272092
if final_left_sym.kind == .aggregate {
@@ -2816,9 +2781,7 @@ fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) !
28162781
}
28172782
if f.is_variadic {
28182783
min_required_params--
2819-
if c.pref.skip_unused && !c.is_builtin_mod {
2820-
c.table.used_features.arr_init = true
2821-
}
2784+
c.markused_array_method(!c.is_builtin_mod, '')
28222785
} else {
28232786
has_decompose := node.args.any(it.expr is ast.ArrayDecompose)
28242787
if has_decompose {
@@ -3437,17 +3400,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
34373400
}
34383401
node.return_type = ast.int_type
34393402
} else if method_name in ['first', 'last', 'pop'] {
3440-
if c.pref.skip_unused && !c.is_builtin_mod {
3441-
if method_name == 'first' {
3442-
c.table.used_features.arr_first = true
3443-
}
3444-
if method_name == 'last' {
3445-
c.table.used_features.arr_last = true
3446-
}
3447-
if method_name == 'pop' {
3448-
c.table.used_features.arr_pop = true
3449-
}
3450-
}
3403+
c.markused_array_method(!c.is_builtin_mod, method_name)
34513404
if node.args.len != 0 {
34523405
c.error('`.${method_name}()` does not have any arguments', arg0.pos)
34533406
}
@@ -3459,9 +3412,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
34593412
node.receiver_type = node.left_type
34603413
}
34613414
} else if method_name == 'delete' {
3462-
if c.pref.skip_unused && !c.is_builtin_mod {
3463-
c.table.used_features.arr_delete = true
3464-
}
3415+
c.markused_array_method(!c.is_builtin_mod, method_name)
34653416
c.check_for_mut_receiver(mut node.left)
34663417
unwrapped_left_sym := c.table.sym(unwrapped_left_type)
34673418
if method := c.table.find_method(unwrapped_left_sym, method_name) {

vlib/v/checker/infix.v

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
5757
}
5858
// `arr << if n > 0 { 10 } else { 11 }` set the right c.expected_type
5959
if node.op == .left_shift && c.table.sym(left_type).kind == .array {
60-
if c.pref.skip_unused && !c.is_builtin_mod && c.mod != 'strings' {
61-
c.table.used_features.index = true
62-
c.table.used_features.arr_init = true
63-
}
60+
c.markused_infiexpr(!c.is_builtin_mod && c.mod != 'strings')
6461
if mut node.right is ast.IfExpr {
6562
if node.right.is_expr && node.right.branches.len > 0 {
6663
mut last_stmt := node.right.branches[0].stmts.last()

vlib/v/checker/interface.v

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
1212
is_js := node.language == .js
1313
if mut decl_sym.info is ast.Interface {
1414
mut has_generic_types := false
15-
if c.pref.skip_unused && decl_sym.mod == 'main' {
16-
c.table.used_features.interfaces = true
17-
}
1815
if node.embeds.len > 0 {
1916
all_embeds := c.expand_iface_embeds(node, 0, node.embeds)
2017
// eprintln('> node.name: $node.name | node.embeds.len: $node.embeds.len | all_embeds: $all_embeds.len')

vlib/v/checker/str.v

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,7 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type {
5353
c.error('expression returning type `char` cannot be used in string interpolation directly, print its address or cast it to an integer instead',
5454
expr.pos())
5555
}
56-
if c.pref.skip_unused && !c.is_builtin_mod {
57-
if !c.table.sym(ftyp).has_method('str') {
58-
c.table.used_features.auto_str = true
59-
} else {
60-
c.table.used_features.print_types[ftyp.idx()] = true
61-
}
62-
if ftyp.is_ptr() {
63-
c.table.used_features.auto_str_ptr = true
64-
}
65-
c.table.used_features.interpolation = true
66-
}
56+
c.markused_string_inter_lit(mut node, ftyp)
6757
c.fail_if_unreadable(expr, ftyp, 'interpolation object')
6858
node.expr_types << ftyp
6959
ftyp_sym := c.table.sym(ftyp)

0 commit comments

Comments
 (0)