From ca236e967e58d4ff428d978f36360ebcbe8f3871 Mon Sep 17 00:00:00 2001 From: Turiiya <34311583+ttytm@users.noreply.github.com> Date: Sun, 17 Nov 2024 07:52:03 +0100 Subject: [PATCH] parser, checker, pref: allow getting notified about unused function params (#22879) --- vlib/v/checker/checker.v | 8 +++- vlib/v/checker/tests/unused_param.out | 14 +++++++ vlib/v/checker/tests/unused_param.vv | 13 +++++++ vlib/v/compiler_errors_test.v | 1 + vlib/v/parser/fn.v | 55 ++++++++++++++------------- vlib/v/pref/pref.v | 4 ++ 6 files changed, 67 insertions(+), 28 deletions(-) create mode 100644 vlib/v/checker/tests/unused_param.out create mode 100644 vlib/v/checker/tests/unused_param.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 56f028b00..1fd062b4e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -289,7 +289,13 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) { ast.Var { if !obj.is_used && obj.name[0] != `_` { if !c.pref.translated && !c.file.is_translated { - c.warn('unused variable: `${obj.name}`', obj.pos) + if obj.is_arg { + if c.pref.show_unused_params { + c.note('unused parameter: `${obj.name}`', obj.pos) + } + } else { + c.warn('unused variable: `${obj.name}`', obj.pos) + } } } if obj.is_mut && !obj.is_changed && !c.is_builtin_mod && obj.name != 'it' { diff --git a/vlib/v/checker/tests/unused_param.out b/vlib/v/checker/tests/unused_param.out new file mode 100644 index 000000000..a286e9204 --- /dev/null +++ b/vlib/v/checker/tests/unused_param.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/unused_param.vv:5:33: notice: unused parameter: `unused_param` + 3 | struct Foo {} + 4 | + 5 | fn (unused_receiver Foo) method(unused_param int) {} + | ~~~~~~~~~~~~ + 6 | + 7 | fn func(unused_param int) {} +vlib/v/checker/tests/unused_param.vv:7:9: notice: unused parameter: `unused_param` + 5 | fn (unused_receiver Foo) method(unused_param int) {} + 6 | + 7 | fn func(unused_param int) {} + | ~~~~~~~~~~~~ + 8 | + 9 | fn func2(_ int) {} diff --git a/vlib/v/checker/tests/unused_param.vv b/vlib/v/checker/tests/unused_param.vv new file mode 100644 index 000000000..d3f353a64 --- /dev/null +++ b/vlib/v/checker/tests/unused_param.vv @@ -0,0 +1,13 @@ +#include + +struct Foo {} + +fn (unused_receiver Foo) method(unused_param int) {} + +fn func(unused_param int) {} + +fn func2(_ int) {} + +pub fn pub_func(unused_param int) {} + +fn C.puts(unused_c_param &char) int diff --git a/vlib/v/compiler_errors_test.v b/vlib/v/compiler_errors_test.v index 654ef4e5f..e01908208 100644 --- a/vlib/v/compiler_errors_test.v +++ b/vlib/v/compiler_errors_test.v @@ -8,6 +8,7 @@ import benchmark const skip_files = [ 'non_existing.vv', // minimize commit diff churn, do not remove + 'vlib/v/checker/tests/unused_param.vv', ] const skip_on_cstrict = [ diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 4648d5364..7b02af8a9 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -442,33 +442,6 @@ fn (mut p Parser) fn_decl() ast.FnDecl { is_variadic = true } params << params_t - if !are_params_type_only { - for k, param in params { - if p.scope.known_var(param.name) { - p.error_with_pos('redefinition of parameter `${param.name}`', param.pos) - return ast.FnDecl{ - scope: unsafe { nil } - } - } - is_stack_obj := !param.typ.has_flag(.shared_f) && (param.is_mut || param.typ.is_ptr()) - p.scope.register(ast.Var{ - name: param.name - typ: param.typ - is_mut: param.is_mut - is_auto_deref: param.is_mut - is_stack_obj: is_stack_obj - pos: param.pos - is_used: true - is_arg: true - ct_type_var: if (!is_method || k > 0) && param.typ.has_flag(.generic) - && !param.typ.has_flag(.variadic) { - .generic_param - } else { - .no_comptime - } - }) - } - } // Return type mut return_type_pos := p.tok.pos() mut return_type := ast.void_type @@ -515,6 +488,34 @@ run them via `v file.v` instead', p.error_with_pos('cannot declare a static function as a receiver method', name_pos) } // Register + if !are_params_type_only { + for k, param in params { + if p.scope.known_var(param.name) { + p.error_with_pos('redefinition of parameter `${param.name}`', param.pos) + return ast.FnDecl{ + scope: unsafe { nil } + } + } + is_stack_obj := !param.typ.has_flag(.shared_f) && (param.is_mut || param.typ.is_ptr()) + p.scope.register(ast.Var{ + name: param.name + typ: param.typ + is_mut: param.is_mut + is_auto_deref: param.is_mut + is_stack_obj: is_stack_obj + pos: param.pos + is_used: is_pub || no_body + || (is_method && rec.type_pos == param.type_pos) || p.builtin_mod + is_arg: true + ct_type_var: if (!is_method || k > 0) && param.typ.has_flag(.generic) + && !param.typ.has_flag(.variadic) { + .generic_param + } else { + .no_comptime + } + }) + } + } if is_method { // Do not allow to modify / add methods to types from other modules // arrays/maps dont belong to a module only their element types do diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 1656b103e..f694a1d5d 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -146,6 +146,7 @@ pub mut: show_c_output bool // -show-c-output, print all cc output even if the code was compiled correctly show_callgraph bool // -show-callgraph, print the program callgraph, in a Graphviz DOT format to stdout show_depgraph bool // -show-depgraph, print the program module dependency graph, in a Graphviz DOT format to stdout + show_unused_params bool // NOTE: temporary until making it a default. dump_c_flags string // `-dump-c-flags file.txt` - let V store all C flags, passed to the backend C compiler in `file.txt`, one C flag/value per line. dump_modules string // `-dump-modules modules.txt` - let V store all V modules, that were used by the compiled program in `modules.txt`, one module per line. dump_files string // `-dump-files files.txt` - let V store all V or .template file paths, that were used by the compiled program in `files.txt`, one path per line. @@ -949,6 +950,9 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin res.parse_line_info(res.line_info) i++ } + '-check-unused-fn-args' { + res.show_unused_params = true + } '-use-coroutines' { res.use_coroutines = true $if macos || linux { -- 2.39.5