18

How can I suppress the "assignment to free variable" warning when byte compiling an emacs lisp file?

I'm actually mostly interested in suppressing it for a specific buffer when using flycheck, but I understand this is just passing off to the byte compiler.

It would also be good to get a list of all warnings / errors that can be suppressed.

UPDATE:
For the sake of completeness, allow me to clarify that there are many (language agnostic) reasons to disable compiler warnings. Some examples: to ease the transition of legacy code into a lint enforced framework, for scratch files and recipes to be run within a live context, to remove noise while fixing higher priority problems, or because the compiler is just wrong.

Drew
  • 75,699
  • 9
  • 109
  • 225
fommil
  • 1,750
  • 11
  • 24
  • 2
    Don't suppress these warnings, fix them. They exist for a reason. –  Jan 13 '16 at 14:06
  • 3
    @lunaryorn no, they are false positives. – fommil Jan 13 '16 at 15:43
  • 2
    With all due respect, and without having seen the specific warnings, I would disagree. False free variable warnings are very scarce, and if the do occur in an amount that'd make you want to silence them, I find it hard to believe that all of them are false positives. I strongly suspect that these warnings do indicate missing `defvar`s or missing `require`s. –  Jan 13 '16 at 16:03
  • see the linked references. You're doing the classic thing of answering a question that was not asked ;-) – fommil Jan 13 '16 at 16:10
  • 4
    I'm sorry but what "linked references" do you refer to? –  Jan 13 '16 at 16:15
  • 4
    When you decide that "the compiler is just wrong", the right way to do silence this warning is to declare the problematic variable with `(defvar the-variable)`. This silences the warning only for that variable, so you can still get it for other variables. – Malabarba Jan 13 '16 at 20:48

1 Answers1

25

For the benefit of clueless readers arriving here, allow me a small digression to say that these warnings generally point to real code issues (and when they don't, you can suppress them on a per-variable basis) so people should research what they mean before disabling them.

Of course, I have no doubt that you know why you need to disable it, so the answer is below.


The answer

In order to disable this (or other) warning, you'll need to set the value of byte-compile-warnings. You can do this as a file-local variable by adding the following snippet to the end of the file.

;; Local Variables:
;; byte-compile-warnings: (not free-vars)
;; End:

You can also set this globally.

You can replace (not free-vars) with (not free-vars callargs unresolved) and whichever other warnings you want to suppress. The full list of warnings that can be included/supressed is found on the variable's docstring (below).

byte-compile-warnings is a variable defined in `bytecomp.el'.
Its value is t

  This variable is safe as a file local variable if its value
  satisfies the predicate which is a byte-compiled expression.

Documentation:
List of warnings that the byte-compiler should issue (t for all).

Elements of the list may be:

  free-vars   references to variables not in the current lexical scope.
  unresolved  calls to unknown functions.
  callargs    function calls with args that don't match the definition.
  redefine    function name redefined from a macro to ordinary function or vice
              versa, or redefined to take a different number of arguments.
  obsolete    obsolete variables and functions.
  noruntime   functions that may not be defined at runtime (typically
              defined only under `eval-when-compile').
  cl-functions    calls to runtime functions (as distinguished from macros and
                  aliases) from the old CL package (not the newer cl-lib).
  interactive-only
          commands that normally shouldn't be called from Lisp code.
  lexical     global/dynamic variables lacking a prefix.
  make-local  calls to make-variable-buffer-local that may be incorrect.
  mapcar      mapcar called for effect.
  constants   let-binding of, or assignment to, constants/nonvariables.
  suspicious  constructs that usually don't do what the coder wanted.

If the list begins with `not', then the remaining elements specify warnings to
suppress.  For example, (not mapcar) will suppress warnings about mapcar.
Malabarba
  • 22,878
  • 6
  • 78
  • 163
  • Note that Flycheck doesn't forward a global setting for this variable to the byte compiler subprocess. I'm not even sure whether it evaluates the local variable. –  Jan 13 '16 at 14:06
  • 2
    @lunaryorn I think the local-var version should work with flycheck. At least, the byte-compiler usually takes care to read local variables before compiling the file. – Malabarba Jan 13 '16 at 17:31
  • @Malabarba I didn't know that, thanks for the information. I presume it'll also read `.dir-locals` then. –  Jan 13 '16 at 17:36
  • 6
    @fommil Sorry, I didn't mean to sound patronizing. I wrote that paragraph because other people might land here when they google this warning, and I wanted them to know that it's a real thing (not just something they should immediately disable). It's not about cleaniness, it's about correctness (code has a different meaning without the defvar). Since you didn't mention why you wanted to disable it, I figured it was worth mentioning that it shouldnt be the first option. – Malabarba Jan 13 '16 at 17:38
  • 7
    @fommil Your question does not include any references to a more specific use case. It reads as a _general_ question, and as such, pointing out that it's _generally_ (but not necessarily _specifically_ in your case) not a good idea to disable all warnings would have to be part of any complete answer about disabling warnings, wouldn't it? You're not the only one reading this answer and you can't expect to be given a specific answer about your specific needs if you don't include these in your question. –  Jan 13 '16 at 17:43
  • 2
    @fommil I've reworded that first paragraph to hopefully read a little better. Let me know what you think. – Malabarba Jan 13 '16 at 17:54
  • while I understand your argument @lunaryorn I do not agree with it. Stack Overflow and corresponding sites are Question / Answer sites, not advice sites. Indeed, questions seeking an opinion should be closed according to the guidelines. The QA format lends itself extremely well to googling. Including more information than is strictly necessary in the question invites off-topic digressions and irrelevant answers. Every question here has a back story, and it doesn't need to be shared, so I like to keep it simple: ask a question, maybe get an answer (if you're lucky). – fommil Jan 13 '16 at 19:26
  • @fommil I think precisely because SX rank well on Google we should strive to provide complete and comprehensive answer, the more of a question is as general as yours. Please try to see our point of view and our intention. While you know how to assess compiler warnings, others may not, and thus disable warnings that they should rather have fixed. I don't think that this intention warrants snarky comments and passive-aggressive edits. We didn't know your background, I'm sorry, but there's no need to get offended. –  Jan 13 '16 at 22:09
  • The answer as it reads now is very good. The original answer, and your comments on the question, were neither complete nor comprehensive: they only provoked a reaction by insisting that the question was wrong. Also, my snarky update has been edited so that it now sounds wise and thoughtful :-) – fommil Jan 13 '16 at 22:42
  • 3
    Nice answer. This answer becomes even more relevant when you use Emacs >=28 with native compilation as you'll get copious byte compile warnings for 3rd party libraries that you probably aren't going to fix since you didn't author them (especially if you use tens of packages). – Joe Aug 11 '21 at 18:30