Byte compilation of my mode:

(defun dict-setup-expansions ()
  "Add `dict-mode' specific expansions."
  (set (make-local-variable 'er/try-expand-list) (list #'dict-mark-article)))

gives warning:

Warning: assignment to free variable `er/try-expand-list'

This is normal situation because er/try-expand-list is defined in external library expand-region.

My mode register extension to expand-region library but it is ok to run my mode without expand-region mode.

I think that proper way to deal with warning is to add declaration:

(defvar er/try-expand-list)

defvar docs say:

The `defvar' form also declares the variable as "special",
so that it is always dynamically bound even if `lexical-binding' is t.

I use -*- lexical-binding: t -*-. Does that mean that without defvar variable er/try-expand-list be in lexical scope and I have real bug?

  • 2
    Side note: you shouldn't quote the symbol in the (defvar er/try-expand-list).
    – JeanPierre
    Mar 27, 2016 at 14:07
  • @JeanPierre Fixed.
    – gavenkoa
    Mar 27, 2016 at 14:33

1 Answer 1


No, set and setq do not declare lexical variables. Only let does. Had you used let here you'd have a bug, but this is fine. The warning exists mostly to catch typos when using dynamic variables.

To make the warning go away use defvar as in your question, but do not quote the symbol.

  • Is wrapping into eval-when-compile redundant to just defvar? I see no warning without eval-when-compile. Seems that eval-when-compile is necessary if use active code, like (require ...)...
    – gavenkoa
    Mar 27, 2016 at 14:35
  • 3
    Wrapping defvar would be redundant.
    – user227
    Mar 27, 2016 at 14:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.