use-package icon indicating copy to clipboard operation
use-package copied to clipboard

defines and functions seem to have no effect at all

Open kirk86 opened this issue 4 years ago • 8 comments

image

kirk86 avatar Oct 10 '19 13:10 kirk86

your Emacs could find use-package in compiler time? please use (eval-when-compile (require 'use-package) to load use-pacakge in compiler time.

conao3 avatar Feb 22 '21 16:02 conao3

Thanks but I already do have that in my config.

kirk86 avatar Apr 07 '21 09:04 kirk86

I'm running into the same issue:

(eval-when-compile
  (require 'use-package))

(use-package eglot
  :functions eglot-managed-p
  :config
  (eglot-managed-p))

I see the function ‘eglot-managed-p’ might not be defined at runtime. The weird thing is if I change the function to something that doesn't exist, the warning goes away:

(eval-when-compile
  (require 'use-package))

(use-package eglot
  :functions eglot-managed-p-doesnt-exist
  :config
  (eglot-managed-p-doesnt-exist))

This code doesn't emit any warnings. I'm not sure why this is happening.

gsingh93 avatar Sep 06 '22 23:09 gsingh93

Can you please try macro-expanding those use-package declarations, to see what the code it's expanded to is doing? That may make the problem and the solution clear.

jwiegley avatar Sep 07 '22 00:09 jwiegley

(setq use-package-expand-minimally t)
(macroexpand '(use-package eglot
                :functions eglot-managed-p
                :config
                (eglot-managed-p)))

Output:

(progn
  (require 'eglot nil nil)
  (eglot-managed-p)
  t)

The other example essentially goes to the same thing, I'm not sure why it's not showing this warning:

(progn
  (require 'eglot nil nil)
  (eglot-managed-p-doesnt-exist)
  t)

Also, here's how it looks without use-package-expand-minimally:

(progn
  (defvar use-package--warning81
    #'(lambda
        (keyword err)
        (let
            ((msg
              (format "%s/%s: %s" 'eglot keyword
                      (error-message-string err))))
          (display-warning 'use-package msg :error))))
  (condition-case-unless-debug err
      (if
          (not
           (require 'eglot nil t))
          (display-warning 'use-package
                           (format "Cannot load %s" 'eglot)
                           :error)
        (condition-case-unless-debug err
            (progn
              (eglot-managed-p)
              t)
          (error
           (funcall use-package--warning81 :config err))))
    (error
     (funcall use-package--warning81 :catch err))))

gsingh93 avatar Sep 07 '22 01:09 gsingh93

When byte-compiling the file, it should declare the function:

(let ((byte-compile-current-file t))
  (macroexpand '(use-package eglot
                  :functions eglot-managed-p
                  :config
                  (eglot-managed-p))))

(progn
  (eval-and-compile
    (declare-function eglot-managed-p "eglot")
    (eval-when-compile
      (with-demoted-errors "Cannot load eglot: %S" nil
                           (unless
                               (featurep 'eglot)
                             (load "eglot" nil t)))))
  (require 'eglot nil nil)
  (eglot-managed-p)
  t)

jwiegley avatar Sep 07 '22 02:09 jwiegley

Thanks! I think I've figured out where the difference is. It seems the warnings show up with use-package-expand-minimally set to nil as opposed to t.

This is the expansion with the variable set to t, this works fine and gives me no warnings:

(let ((byte-compile-current-file t)
      (use-package-expand-minimally t))
  (macroexpand '(use-package eglot
                  :functions eglot-managed-p
                  :config
                  (eglot-managed-p))))

(progn
  (eval-and-compile
    (declare-function eglot-managed-p "eglot")
    (eval-when-compile
      (with-demoted-errors "Cannot load eglot: %S" nil
                           (unless
                               (featurep 'eglot)
                             (load "eglot" nil t)))))
  (require 'eglot nil nil)
  (eglot-managed-p)
  t)

This is with the variable set to nil, this gives me Warning: the function ‘eglot-managed-p’ might not be defined at runtime:

(let ((byte-compile-current-file t)
      (use-package-expand-minimally nil))
  (macroexpand '(use-package eglot
                  :functions eglot-managed-p
                  :config
                  (eglot-managed-p))))

(progn
  (eval-and-compile
    (declare-function eglot-managed-p "eglot")
    (eval-when-compile
      (with-demoted-errors "Cannot load eglot: %S" nil
                           (unless
                               (featurep 'eglot)
                             (load "eglot" nil t)))))
  (defvar use-package--warning79
    #'(lambda
        (keyword err)
        (let
            ((msg
              (format "%s/%s: %s" 'eglot keyword
                      (error-message-string err))))
          (display-warning 'use-package msg :error))))
  (condition-case-unless-debug err
      (if
          (not
           (require 'eglot nil t))
          (display-warning 'use-package
                           (format "Cannot load %s" 'eglot)
                           :error)
        (condition-case-unless-debug err
            (progn
              (eglot-managed-p)
              t)
          (error
           (funcall use-package--warning79 :config err))))
    (error
     (funcall use-package--warning79 :catch err))))

gsingh93 avatar Sep 07 '22 05:09 gsingh93

That's very interesting, something about the structure of the code that follows changes the reporting behavior here. Good find!

jwiegley avatar Sep 08 '22 03:09 jwiegley