Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into fix_markused_auto_str
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed Jan 17, 2025
2 parents e18f85c + 1b9f15d commit 0a49127
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 170 deletions.
1 change: 0 additions & 1 deletion vlib/v/ast/table.v
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import v.util
@[heap; minify]
pub struct UsedFeatures {
pub mut:
interfaces bool // interface
dump bool // dump()
index bool // string[0]
range_index bool // string[0..1]
Expand Down
57 changes: 10 additions & 47 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -1392,9 +1392,8 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast.
}

fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return_type ast.Type, expr ast.Expr) {
if c.pref.skip_unused && !c.is_builtin_mod && node.kind != .absent && c.mod != 'strings' {
c.table.used_features.option_or_result = true
}
c.markused_option_or_result(!c.is_builtin_mod && node.kind != .absent && c.mod != 'strings')

if node.kind == .propagate_option {
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.option)
&& !c.table.cur_fn.is_main && !c.table.cur_fn.is_test && !c.inside_const {
Expand Down Expand Up @@ -1794,16 +1793,12 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
c.check_or_expr(node.or_block, unwrapped_typ, c.expected_or_type, node)
c.expected_or_type = ast.void_type
}
if c.pref.skip_unused && node.or_block.kind != .absent
&& !c.table.used_features.option_or_result {
c.table.used_features.option_or_result = true
}
c.markused_option_or_result(node.or_block.kind != .absent
&& !c.table.used_features.option_or_result)
return field.typ
}
if mut method := c.table.sym(c.unwrap_generic(typ)).find_method_with_generic_parent(field_name) {
if c.pref.skip_unused && typ.has_flag(.generic) {
c.table.used_features.comptime_calls['${int(method.params[0].typ)}.${field_name}'] = true
}
c.markused_comptime_call(typ.has_flag(.generic), '${int(method.params[0].typ)}.${field_name}')
if c.expected_type != 0 && c.expected_type != ast.none_type {
fn_type := ast.new_type(c.table.find_or_register_fn_type(method, false, true))
// if the expected type includes the receiver, don't hide it behind a closure
Expand Down Expand Up @@ -2383,15 +2378,7 @@ fn (mut c Checker) assert_stmt(mut node ast.AssertStmt) {
cur_exp_typ := c.expected_type
c.expected_type = ast.bool_type
assert_type := c.check_expr_option_or_result_call(node.expr, c.expr(mut node.expr))
if c.pref.skip_unused && !c.table.used_features.auto_str && !c.is_builtin_mod
&& mut node.expr is ast.InfixExpr {
if !c.table.sym(c.unwrap_generic(node.expr.left_type)).has_method('str') {
c.table.used_features.auto_str = true
}
if !c.table.sym(c.unwrap_generic(node.expr.right_type)).has_method('str') {
c.table.used_features.auto_str = true
}
}
c.markused_assertstmt_auto_str(mut node)
if assert_type != ast.bool_type_idx {
atype_name := c.table.sym(assert_type).name
c.error('assert can be used only with `bool` expressions, but found `${atype_name}` instead',
Expand Down Expand Up @@ -3051,17 +3038,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
c.table.used_features.dump = true
c.expected_type = ast.string_type
node.expr_type = c.expr(mut node.expr)
if c.pref.skip_unused && !c.is_builtin_mod {
if !c.table.sym(c.unwrap_generic(node.expr_type)).has_method('str') {
c.table.used_features.auto_str = true
if node.expr_type.is_ptr() {
c.table.used_features.auto_str_ptr = true
}
} else {
c.table.used_features.print_types[node.expr_type.idx()] = true
}
c.table.used_features.print_types[ast.int_type_idx] = true
}
c.markused_dumpexpr(mut node)
if c.comptime.inside_comptime_for && mut node.expr is ast.Ident {
if node.expr.ct_expr {
node.expr_type = c.type_resolver.get_type(node.expr as ast.Ident)
Expand Down Expand Up @@ -3284,10 +3261,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
ast.StructInit {
if node.unresolved {
mut expr_ := c.table.resolve_init(node, c.unwrap_generic(node.typ))
if c.pref.skip_unused && c.table.used_features.used_maps == 0
&& expr_ is ast.MapInit {
c.table.used_features.used_maps++
}
c.markused_used_maps(c.table.used_features.used_maps == 0 && expr_ is ast.MapInit)
return c.expr(mut expr_)
}
mut inited_fields := []string{}
Expand Down Expand Up @@ -3374,16 +3348,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
to_type
}
final_to_is_ptr := to_type.is_ptr() || final_to_type.is_ptr()
if c.pref.skip_unused && !c.is_builtin_mod {
if c.table.used_features.used_maps == 0 && mut final_to_sym.info is ast.SumType {
if final_to_sym.info.variants.any(c.table.final_sym(it).kind == .map) {
c.table.used_features.used_maps++
}
}
if c.mod !in ['strings', 'math.bits'] && to_type.is_ptr() {
c.table.used_features.cast_ptr = true
}
}
c.markused_castexpr(mut node, to_type, mut final_to_sym)
if to_type.has_flag(.result) {
c.error('casting to Result type is forbidden', node.pos)
}
Expand Down Expand Up @@ -4003,9 +3968,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
c.error('`mut` is not allowed with `=` (use `:=` to declare a variable)',
node.pos)
}
if c.pref.skip_unused && !c.is_builtin_mod && node.language == .v && node.name.contains('.') {
c.table.used_features.external_types = true
}
c.markused_external_type(!c.is_builtin_mod && node.language == .v && node.name.contains('.'))
if mut obj := node.scope.find(node.name) {
match mut obj {
ast.GlobalField {
Expand Down
45 changes: 3 additions & 42 deletions vlib/v/checker/comptime.v
Original file line number Diff line number Diff line change
Expand Up @@ -133,32 +133,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
// check each arg expression
node.args[i].typ = c.expr(mut arg.expr)
}
if c.pref.skip_unused {
c.table.used_features.comptime_calls['${int(c.unwrap_generic(c.comptime.comptime_for_method.receiver_type))}.${c.comptime.comptime_for_method.name}'] = true
if c.inside_anon_fn {
// $method passed to anon fn, mark all methods as used
sym := c.table.sym(c.unwrap_generic(node.left_type))
for m in sym.get_methods() {
c.table.used_features.comptime_calls['${int(c.unwrap_generic(m.receiver_type))}.${m.name}'] = true
if node.args.len > 0 && m.params.len > 0 {
last_param := m.params.last().typ
if (last_param.is_int() || last_param.is_bool())
&& c.table.final_sym(node.args.last().typ).kind == .array {
c.table.used_features.comptime_calls['${ast.string_type_idx}.${c.table.type_to_str(m.params.last().typ)}'] = true
}
}
}
} else {
m := c.comptime.comptime_for_method
if node.args.len > 0 && m.params.len > 0 {
last_param := m.params.last().typ
if (last_param.is_int() || last_param.is_bool())
&& c.table.final_sym(node.args.last().typ).kind == .array {
c.table.used_features.comptime_calls['${ast.string_type_idx}.${c.table.type_to_str(m.params.last().typ)}'] = true
}
}
}
}
c.markused_comptimecall(mut node)
c.stmts_ending_with_expression(mut node.or_block.stmts, c.expected_or_type)
return c.type_resolver.get_type(node)
}
Expand Down Expand Up @@ -223,9 +198,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
c.error('could not find method `${method_name}`', node.method_pos)
return ast.void_type
}
if c.pref.skip_unused {
c.table.used_features.comptime_calls['${int(left_type)}.${method_name}'] = true
}
c.markused_comptime_call(true, '${int(left_type)}.${method_name}')
node.result_type = f.return_type
return f.return_type
}
Expand Down Expand Up @@ -312,19 +285,7 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
unwrapped_expr_type := c.unwrap_generic(field.typ)
tsym := c.table.sym(unwrapped_expr_type)
c.table.dumps[int(unwrapped_expr_type.clear_flags(.option, .result, .atomic_f))] = tsym.cname
if c.pref.skip_unused {
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 {
c.table.used_features.used_maps++
} else if final_sym.info is ast.SumType {
if final_sym.info.variants.any(c.table.final_sym(it).kind == .map) {
c.table.used_features.used_maps++
}
}
}
}
c.markused_comptimefor(mut node, unwrapped_expr_type)
if tsym.kind == .array_fixed {
info := tsym.info as ast.ArrayFixed
if !info.is_fn_ret {
Expand Down
4 changes: 1 addition & 3 deletions vlib/v/checker/containers.v
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
}
}
ast.Map {
if c.pref.skip_unused && !c.is_builtin_mod {
c.table.used_features.arr_map = true
}
c.markused_array_method(!c.is_builtin_mod, 'map')
}
else {}
}
Expand Down
67 changes: 8 additions & 59 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -756,22 +756,10 @@ fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
c.check_or_expr(node.or_block, typ, c.expected_or_type, node)
c.inside_or_block_value = old_inside_or_block_value
} else if node.or_block.kind == .propagate_option || node.or_block.kind == .propagate_result {
if c.pref.skip_unused && !c.is_builtin_mod && c.mod != 'strings' {
c.table.used_features.option_or_result = true
}
c.markused_option_or_result(!c.is_builtin_mod && c.mod != 'strings')
}
c.expected_or_type = old_expected_or_type
if c.pref.skip_unused && !c.is_builtin_mod && c.mod == 'main'
&& !c.table.used_features.external_types {
if node.is_method {
if c.table.sym(node.left_type).is_builtin() {
c.table.used_features.external_types = true
}
} else if node.name.contains('.') {
c.table.used_features.external_types = true
}
}

c.markused_call_expr(mut node)
if !c.inside_const && c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.is_main
&& !c.table.cur_fn.is_test {
// TODO: use just `if node.or_block.kind == .propagate_result && !c.table.cur_fn.return_type.has_flag(.result) {` after the deprecation for ?!Type
Expand Down Expand Up @@ -1422,22 +1410,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
if node.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)
if c.pref.skip_unused && !c.is_builtin_mod && c.mod != 'math.bits'
&& node.args[0].expr !is ast.StringLiteral {
if (node.args[0].expr is ast.CallExpr && node.args[0].expr.is_method
&& node.args[0].expr.name == 'str')
|| !c.table.sym(c.unwrap_generic(node.args[0].typ)).has_method('str') {
c.table.used_features.auto_str = true
} else {
if node.args[0].typ.has_option_or_result() {
c.table.used_features.option_or_result = true
}
c.table.used_features.print_types[node.args[0].typ.idx()] = true
}
if node.args[0].typ.is_ptr() {
c.table.used_features.auto_str_ptr = true
}
}
c.markused_fn_call(mut node)
return func.return_type
}
// `return error(err)` -> `return err`
Expand Down Expand Up @@ -1982,15 +1955,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
continue_check = false
return ast.void_type
}
if c.pref.skip_unused {
if !left_type.has_flag(.generic) && mut left_expr is ast.Ident {
if left_expr.obj is ast.Var && left_expr.obj.ct_type_var == .smartcast {
c.table.used_features.comptime_calls['${int(left_type)}.${node.name}'] = true
}
} else if left_type.has_flag(.generic) {
c.table.used_features.comptime_calls['${int(c.unwrap_generic(left_type))}.${node.name}'] = true
}
}
c.markused_method_call(mut node, mut left_expr, left_type)
c.expected_type = left_type
mut is_generic := left_type.has_flag(.generic)
node.left_type = left_type
Expand Down Expand Up @@ -2121,9 +2086,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
if embed_types.len != 0 {
is_method_from_embed = true
node.from_embed_types = embed_types
if c.pref.skip_unused && node.left_type.has_flag(.generic) {
c.table.used_features.comptime_calls['${int(method.receiver_type)}.${method.name}'] = true
}
c.markused_comptime_call(node.left_type.has_flag(.generic), '${int(method.receiver_type)}.${method.name}')
}
}
if final_left_sym.kind == .aggregate {
Expand Down Expand Up @@ -2818,9 +2781,7 @@ fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) !
}
if f.is_variadic {
min_required_params--
if c.pref.skip_unused && !c.is_builtin_mod {
c.table.used_features.arr_init = true
}
c.markused_array_method(!c.is_builtin_mod, '')
} else {
has_decompose := node.args.any(it.expr is ast.ArrayDecompose)
if has_decompose {
Expand Down Expand Up @@ -3439,17 +3400,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
}
node.return_type = ast.int_type
} else if method_name in ['first', 'last', 'pop'] {
if c.pref.skip_unused && !c.is_builtin_mod {
if method_name == 'first' {
c.table.used_features.arr_first = true
}
if method_name == 'last' {
c.table.used_features.arr_last = true
}
if method_name == 'pop' {
c.table.used_features.arr_pop = true
}
}
c.markused_array_method(!c.is_builtin_mod, method_name)
if node.args.len != 0 {
c.error('`.${method_name}()` does not have any arguments', arg0.pos)
}
Expand All @@ -3461,9 +3412,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
node.receiver_type = node.left_type
}
} else if method_name == 'delete' {
if c.pref.skip_unused && !c.is_builtin_mod {
c.table.used_features.arr_delete = true
}
c.markused_array_method(!c.is_builtin_mod, method_name)
c.check_for_mut_receiver(mut node.left)
unwrapped_left_sym := c.table.sym(unwrapped_left_type)
if method := c.table.find_method(unwrapped_left_sym, method_name) {
Expand Down
5 changes: 1 addition & 4 deletions vlib/v/checker/infix.v
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
}
// `arr << if n > 0 { 10 } else { 11 }` set the right c.expected_type
if node.op == .left_shift && c.table.sym(left_type).kind == .array {
if c.pref.skip_unused && !c.is_builtin_mod && c.mod != 'strings' {
c.table.used_features.index = true
c.table.used_features.arr_init = true
}
c.markused_infiexpr(!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()
Expand Down
3 changes: 0 additions & 3 deletions vlib/v/checker/interface.v
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
is_js := node.language == .js
if mut decl_sym.info is ast.Interface {
mut has_generic_types := false
if c.pref.skip_unused && decl_sym.mod == 'main' {
c.table.used_features.interfaces = true
}
if node.embeds.len > 0 {
all_embeds := c.expand_iface_embeds(node, 0, node.embeds)
// eprintln('> node.name: $node.name | node.embeds.len: $node.embeds.len | all_embeds: $all_embeds.len')
Expand Down
12 changes: 1 addition & 11 deletions vlib/v/checker/str.v
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,7 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type {
c.error('expression returning type `char` cannot be used in string interpolation directly, print its address or cast it to an integer instead',
expr.pos())
}
if c.pref.skip_unused && !c.is_builtin_mod {
if !c.table.sym(ftyp).has_method('str') {
c.table.used_features.auto_str = true
} else {
c.table.used_features.print_types[ftyp.idx()] = true
}
if ftyp.is_ptr() {
c.table.used_features.auto_str_ptr = true
}
c.table.used_features.interpolation = true
}
c.markused_string_inter_lit(mut node, ftyp)
c.fail_if_unreadable(expr, ftyp, 'interpolation object')
node.expr_types << ftyp
ftyp_sym := c.table.sym(ftyp)
Expand Down
Loading

0 comments on commit 0a49127

Please sign in to comment.