-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unused Declaration Detection #4377
Conversation
This is great! I still need to review carefully but after a cursory skim it certainly looks good to me. Haven't tried it but will a recursive use silence the warning even if a function is never called non-recursively? |
Finally got a chance to play with this... Looks good but some issues remain. The repl will complain on almost every interaction, because you typically define stuff before using it later. Perhaps we should just suppress the warnings there.
A recursive but unused functions is accepted sans warning. Ditto for mutually recursive functions. OCaml seems to be able to detect and warn about these, so if easy to fix, it would be nice to do the same. But perhaps it's non-trivial, in which case we could live with it for now. I wonder if we should go the extra step and warn about a reference to a silenced identifier? OCaml does not, so perhaps a good enough reason not to. I.e. should
produce a (different) warning or not? Some simple cases I tried:
|
src/mo_frontend/typing.ml
Outdated
(* Unused declaration detection *) | ||
|
||
let emit_unused_warnings env = | ||
let emit (id, region) = warn env region "M0194" "Unused declaration %s" id in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let emit (id, region) = warn env region "M0194" "Unused declaration %s" id in | |
let emit (id, region) = warn env region "M0194" "unused identifier %s" id in |
For consistency with other errors, probably best to lowercase the message. Also, the manual uses the terminology identifier/binding rather than variable/declaration but I don't feel that strongly about it.
I had a quick look at how ocaml does more accurate unused binding declarations for recursive bindings and found this comment. Not sure I grokk it but perhaps it'll inspire you: https://github.com/ocaml/ocaml/blob/trunk/typing/typecore.ml#L6075
|
I just tried building motoko-base/test and got some warnings we should probably fix: But I guess this raises the question whether we should disable the production of warnings on code from third party libraries (perhaps just from every package). Whaddya think? |
src/mo_frontend/typing.ml
Outdated
let detect_unused env inner_variables = | ||
if env.check_unused then | ||
T.Env.iter (fun id (_, at) -> | ||
if (is_unused_declaration env id) && (not (ignore_warning_for_id id)) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re-order conjunction to make it cheaper?
Code refactoring curating unused program declarations as reported by dfinity/motoko#4377 Co-authored-by: Claudio Russo <claudio@dfinity.org>
* don't check for unused idents in repl * add package option to FilePath * refactor to use package option * refactor * adjust LSP code * change error message and terminology * update test output (deleting ic-ref-run results) * appease formatter * refact compare_unused_warning to match other comparisons * adjust test-moc.js * changelog++; newlines * add an explanation * improve text * typos * manually revert clobbered file * update repl output * update repl output * rewrite sed * Update src/lang_utils/error_codes/M0194.md * Update M0194.md
Thank you very much for having improved and extended this PR and brought it to the quality level for merging it with master. As for the detection of unused recursion, I also believe that we would need to do some transitive closure analysis (like Ocaml also does). As this is however different to the current design, I believe it is pragmatic to add this later. |
Unused Declaration Detection
Detection of unused program declarations with compiler warnings.
Program example
example.mo
:Compiler messages:
Coverage
The analysis detects the following unused declarations:
Special aspects:
Warnings
The warning of an unused declaration can be suppressed by prefixing the identifier by an underscore.
Example:
Tweaks from #4407
The repl can't know the rest of the interaction so any warning is premature and a nuisance.
Future: we could suppress all warnings, not just unused declarations - from imported package code this way, should we want to. A --lint mode could re-enable them for further auditing. The rationale is that the warnings are of interest to and actionable on only by the author of the package, not the client.
Future Work
The following analyses are not yet implemented but would be beneficial to support:
let
instead ofvar
.