]> code.delx.au - gnu-emacs/blobdiff - lisp/emacs-lisp/bytecomp.el
Merge branch 'emacs-25-merge'
[gnu-emacs] / lisp / emacs-lisp / bytecomp.el
index f0d2ee48ed29a1cfbe77d8d92fba056130f8ce8b..b5b618e87d7a74d2daf4a04ad40485f1f4721963 100644 (file)
@@ -265,8 +265,8 @@ This option is enabled by default because it reduces Emacs memory usage."
 
 (defcustom byte-optimize-log nil
   "If non-nil, the byte-compiler will log its optimizations.
-If this is 'source, then only source-level optimizations will be logged.
-If it is 'byte, then only byte-level optimizations will be logged.
+If this is `source', then only source-level optimizations will be logged.
+If it is `byte', then only byte-level optimizations will be logged.
 The information is logged to `byte-compile-log-buffer'."
   :group 'bytecomp
   :type '(choice (const :tag "none" nil)
@@ -348,7 +348,7 @@ else the global value will be modified."
 ;;;###autoload
 (defun byte-compile-enable-warning (warning)
   "Change `byte-compile-warnings' to enable WARNING.
-If `byte-compile-warnings' is `t', do nothing.  Otherwise, if the
+If `byte-compile-warnings' is t, do nothing.  Otherwise, if the
 first element is `not', remove WARNING, else add it.
 Normally you should let-bind `byte-compile-warnings' before calling this,
 else the global value will be modified."
@@ -397,7 +397,7 @@ invoked interactively are excluded from this list."
   "Alist of functions and their call tree.
 Each element looks like
 
-  \(FUNCTION CALLERS CALLS\)
+  (FUNCTION CALLERS CALLS)
 
 where CALLERS is a list of functions that call FUNCTION, and CALLS
 is a list of functions for which calls were generated while compiling
@@ -456,10 +456,20 @@ Return the compile-time value of FORM."
                               (byte-compile-recurse-toplevel
                                (macroexp-progn body)
                                (lambda (form)
-                                 (setf result
-                                       (byte-compile-eval
-                                        (byte-compile-top-level
-                                         (byte-compile-preprocess form))))))
+                                 ;; Insulate the following variables
+                                 ;; against changes made in the
+                                 ;; subsidiary compilation.  This
+                                 ;; prevents spurious warning
+                                 ;; messages: "not defined at runtime"
+                                 ;; etc.
+                                 (let ((byte-compile-unresolved-functions
+                                        byte-compile-unresolved-functions)
+                                       (byte-compile-new-defuns
+                                        byte-compile-new-defuns))
+                                   (setf result
+                                         (byte-compile-eval
+                                          (byte-compile-top-level
+                                           (byte-compile-preprocess form)))))))
                               (list 'quote result))))
     (eval-and-compile . ,(lambda (&rest body)
                            (byte-compile-recurse-toplevel
@@ -503,6 +513,11 @@ defined with incorrect args.")
 Used for warnings about calling a function that is defined during compilation
 but won't necessarily be defined when the compiled file is loaded.")
 
+(defvar byte-compile-new-defuns nil
+  "List of (runtime) functions defined in this compilation run.
+This variable is used to qualify `byte-compile-noruntime-functions' when
+outputting warnings about functions not being defined at runtime.")
+
 ;; Variables for lexical binding
 (defvar byte-compile--lexical-environment nil
   "The current lexical environment.")
@@ -973,7 +988,7 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'."
          (print-level 4)
          (print-length 4))
       (byte-compile-log-1
-       (format
+       (format-message
        ,format-string
        ,@(mapcar
           (lambda (x) (if (symbolp x) (list 'prin1-to-string x) x))
@@ -1120,7 +1135,8 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'."
                pt)
           (when dir
             (unless was-same
-              (insert (format "Leaving directory `%s'\n" default-directory))))
+              (insert (format-message "Leaving directory `%s'\n"
+                                       default-directory))))
           (unless (bolp)
             (insert "\n"))
           (setq pt (point-marker))
@@ -1135,8 +1151,8 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'."
           (when dir
             (setq default-directory dir)
             (unless was-same
-              (insert (format "Entering directory `%s'\n"
-                               default-directory))))
+              (insert (format-message "Entering directory `%s'\n"
+                                       default-directory))))
           (setq byte-compile-last-logged-file byte-compile-current-file
                 byte-compile-last-warned-form nil)
           ;; Do this after setting default-directory.
@@ -1154,7 +1170,7 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'."
 
 (defun byte-compile-warn (format &rest args)
   "Issue a byte compiler warning; use (format FORMAT ARGS...) for message."
-  (setq format (apply 'format format args))
+  (setq format (apply #'format-message format args))
   (if byte-compile-error-on-warn
       (error "%s" format)              ; byte-compile-file catches and logs it
     (byte-compile-log-warning format t :warning)))
@@ -1417,7 +1433,7 @@ extra args."
                      (`(lambda ,args . ,_) args)
                      (`(closure ,_ ,args . ,_) args)
                      ((pred byte-code-function-p) (aref old 0))
-                     (t '(&rest def)))))
+                     (_ '(&rest def)))))
             (sig2 (byte-compile-arglist-signature arglist)))
         (unless (byte-compile-arglist-signatures-congruent-p sig1 sig2)
           (byte-compile-set-symbol-position name)
@@ -1502,8 +1518,9 @@ extra args."
       ;; Separate the functions that will not be available at runtime
       ;; from the truly unresolved ones.
       (dolist (f byte-compile-unresolved-functions)
-       (setq f (car f))
-       (if (fboundp f) (push f noruntime) (push f unresolved)))
+        (setq f (car f))
+        (when (not (memq f byte-compile-new-defuns))
+          (if (fboundp f) (push f noruntime) (push f unresolved))))
       ;; Complain about the no-run-time functions
       (byte-compile-print-syms
        "the function `%s' might not be defined at runtime."
@@ -1690,7 +1707,7 @@ Any other non-nil value of ARG means to ask the user.
 If optional argument LOAD is non-nil, loads the file after compiling.
 
 If compilation is needed, this functions returns the result of
-`byte-compile-file'; otherwise it returns 'no-byte-compile."
+`byte-compile-file'; otherwise it returns `no-byte-compile'."
   (interactive
    (let ((file buffer-file-name)
         (file-name nil)
@@ -1900,7 +1917,10 @@ With argument ARG, insert value in current buffer after the form."
                   (let ((read-with-symbol-positions (current-buffer))
                         (read-symbol-positions-list nil))
                     (displaying-byte-compile-warnings
-                     (byte-compile-sexp (read (current-buffer)))))
+                     (byte-compile-sexp
+                       (eval-sexp-add-defvars
+                        (read (current-buffer))
+                        byte-compile-read-position))))
                    lexical-binding)))
       (cond (arg
             (message "Compiling from buffer... done.")
@@ -1957,6 +1977,8 @@ With argument ARG, insert value in current buffer after the form."
        ;; compiled.  A: Yes!  b-c-u-f might contain dross from a
        ;; previous byte-compile.
        (setq byte-compile-unresolved-functions nil)
+        (setq byte-compile-noruntime-functions nil)
+        (setq byte-compile-new-defuns nil)
 
        ;; Compile the forms from the input buffer.
        (while (progn
@@ -2283,8 +2305,7 @@ list that represents a doc string reference.
      ;; byte-compile-warn-about-unresolved-functions.
      (if (memq funsym byte-compile-noruntime-functions)
          (setq byte-compile-noruntime-functions
-               (delq funsym byte-compile-noruntime-functions)
-               byte-compile-noruntime-functions)
+               (delq funsym byte-compile-noruntime-functions))
        (setq byte-compile-unresolved-functions
              (delq (assq funsym byte-compile-unresolved-functions)
                    byte-compile-unresolved-functions)))))
@@ -2342,8 +2363,21 @@ list that represents a doc string reference.
 (defun byte-compile-file-form-require (form)
   (let ((args (mapcar 'eval (cdr form)))
        (hist-orig load-history)
-       hist-new)
+       hist-new prov-cons)
     (apply 'require args)
+
+    ;; Record the functions defined by the require in `byte-compile-new-defuns'.
+    (setq hist-new load-history)
+    (setq prov-cons (cons 'provide (car args)))
+    (while (and hist-new
+                (not (member prov-cons (car hist-new))))
+      (setq hist-new (cdr hist-new)))
+    (when hist-new
+      (dolist (x (car hist-new))
+        (when (and (consp x)
+                   (memq (car x) '(defun t)))
+          (push (cdr x) byte-compile-new-defuns))))
+
     (when (byte-compile-warning-enabled-p 'cl-functions)
       ;; Detect (require 'cl) in a way that works even if cl is already loaded.
       (if (member (car args) '("cl" cl))
@@ -2399,6 +2433,7 @@ not to take responsibility for the actual compilation of the code."
          (byte-compile-current-form name)) ; For warnings.
 
     (byte-compile-set-symbol-position name)
+    (push name byte-compile-new-defuns)
     ;; When a function or macro is defined, add it to the call tree so that
     ;; we can tell when functions are not used.
     (if byte-compile-generate-call-tree
@@ -2584,7 +2619,9 @@ If FORM is a lambda or a macro, byte-compile it as a function."
                  (if (symbolp form) form "provided"))
         fun)
        (t
-        (when (symbolp form)
+        (when (or (symbolp form) (eq (car-safe fun) 'closure))
+          ;; `fun' is a function *value*, so try to recover its corresponding
+          ;; source code.
           (setq lexical-binding (eq (car fun) 'closure))
           (setq fun (byte-compile--reify-function fun)))
         ;; Expand macros.
@@ -2920,11 +2957,17 @@ for symbols generated by the byte compiler itself."
 
 ;; Special macro-expander used during byte-compilation.
 (defun byte-compile-macroexpand-declare-function (fn file &rest args)
-  (push (cons fn
-              (if (and (consp args) (listp (car args)))
-                  (list 'declared (car args))
-                t))                     ; Arglist not specified.
-        byte-compile-function-environment)
+  (let ((gotargs (and (consp args) (listp (car args))))
+       (unresolved (assq fn byte-compile-unresolved-functions)))
+    (when unresolved         ; function was called before declaration
+      (if (and gotargs (byte-compile-warning-enabled-p 'callargs))
+         (byte-compile-arglist-warn fn (car args) nil)
+       (setq byte-compile-unresolved-functions
+             (delq unresolved byte-compile-unresolved-functions))))
+    (push (cons fn (if gotargs
+                      (list 'declared (car args))
+                    t))                     ; Arglist not specified.
+         byte-compile-function-environment))
   ;; We are stating that it _will_ be defined at runtime.
   (setq byte-compile-noruntime-functions
         (delq fn byte-compile-noruntime-functions))
@@ -2973,7 +3016,7 @@ for symbols generated by the byte compiler itself."
             (`(',var . ,_)
              (when (assq var byte-compile-lexical-variables)
                (byte-compile-log-warning
-                (format "%s cannot use lexical var `%s'" fn var)
+                (format-message "%s cannot use lexical var `%s'" fn var)
                 nil :error)))))
         (when (macroexp--const-symbol-p fn)
           (byte-compile-warn "`%s' called as a function" fn))
@@ -2982,11 +3025,13 @@ for symbols generated by the byte compiler itself."
          (byte-compile-warn "`%s' is for interactive use only%s"
                             fn
                             (cond ((stringp interactive-only)
-                                   (format "; %s" interactive-only))
+                                   (format "; %s"
+                                           (substitute-command-keys
+                                            interactive-only)))
                                   ((and (symbolp 'interactive-only)
                                         (not (eq interactive-only t)))
-                                   (format "; use `%s' instead."
-                                           interactive-only))
+                                   (format-message "; use `%s' instead."
+                                                    interactive-only))
                                   (t "."))))
         (if (eq (car-safe (symbol-function (car form))) 'macro)
             (byte-compile-log-warning
@@ -3118,7 +3163,7 @@ for symbols generated by the byte compiler itself."
   (cond ((or (not (symbolp var)) (macroexp--const-symbol-p var))
         (when (byte-compile-warning-enabled-p 'constants)
           (byte-compile-warn (if (eq access-type 'let-bind)
-                                 "attempt to let-bind %s `%s`"
+                                 "attempt to let-bind %s `%s'"
                                "variable reference to %s `%s'")
                              (if (symbolp var) "constant" "nonvariable")
                              (prin1-to-string var))))
@@ -3606,8 +3651,8 @@ discarding."
 
 (defun byte-compile-quo (form)
   (let ((len (length form)))
-    (cond ((<= len 2)
-          (byte-compile-subr-wrong-args form "2 or more"))
+    (cond ((< len 2)
+          (byte-compile-subr-wrong-args form "1 or more"))
          ((= len 3)
           (byte-compile-two-args form))
          (t
@@ -3696,16 +3741,25 @@ discarding."
 (byte-defop-compiler-1 quote)
 
 (defun byte-compile-setq (form)
-  (let ((args (cdr form)))
-    (if args
-       (while args
-         (byte-compile-form (car (cdr args)))
-         (or byte-compile--for-effect (cdr (cdr args))
-             (byte-compile-out 'byte-dup 0))
-         (byte-compile-variable-set (car args))
-         (setq args (cdr (cdr args))))
-      ;; (setq), with no arguments.
-      (byte-compile-form nil byte-compile--for-effect))
+  (let* ((args (cdr form))
+         (len (length args)))
+    (if (= (logand len 1) 1)
+        (progn
+          (byte-compile-log-warning
+           (format "missing value for `%S' at end of setq" (car (last args)))
+           nil :error)
+          (byte-compile-form
+           `(signal 'wrong-number-of-arguments '(setq ,len))
+           byte-compile--for-effect))
+      (if args
+          (while args
+            (byte-compile-form (car (cdr args)))
+            (or byte-compile--for-effect (cdr (cdr args))
+                (byte-compile-out 'byte-dup 0))
+            (byte-compile-variable-set (car args))
+            (setq args (cdr (cdr args))))
+        ;; (setq), with no arguments.
+        (byte-compile-form nil byte-compile--for-effect)))
     (setq byte-compile--for-effect nil)))
 
 (defun byte-compile-setq-default (form)
@@ -3818,11 +3872,11 @@ discarding."
   "Execute forms in BODY, potentially guarded by CONDITION.
 CONDITION is a variable whose value is a test in an `if' or `cond'.
 BODY is the code to compile in the first arm of the if or the body of
-the cond clause.  If CONDITION's value is of the form (fboundp 'foo)
-or (boundp 'foo), the relevant warnings from BODY about foo's
+the cond clause.  If CONDITION's value is of the form (fboundp \\='foo)
+or (boundp \\='foo), the relevant warnings from BODY about foo's
 being undefined (or obsolete) will be suppressed.
 
-If CONDITION's value is (not (featurep 'emacs)) or (featurep 'xemacs),
+If CONDITION's value is (not (featurep \\='emacs)) or (featurep \\='xemacs),
 that suppresses all warnings during execution of BODY."
   (declare (indent 1) (debug t))
   `(let* ((fbound-list (byte-compile-find-bound-condition
@@ -3959,8 +4013,13 @@ that suppresses all warnings during execution of BODY."
     (setq byte-compile--for-effect nil)))
 
 (defun byte-compile-funcall (form)
-  (mapc 'byte-compile-form (cdr form))
-  (byte-compile-out 'byte-call (length (cdr (cdr form)))))
+  (if (cdr form)
+      (progn
+        (mapc 'byte-compile-form (cdr form))
+        (byte-compile-out 'byte-call (length (cdr (cdr form)))))
+    (byte-compile-log-warning "`funcall' called with no arguments" nil :error)
+    (byte-compile-form '(signal 'wrong-number-of-arguments '(funcall 0))
+                       byte-compile--for-effect)))
 
 \f
 ;; let binding
@@ -4410,7 +4469,7 @@ binding slots have been popped."
       ;; which is to call back byte-compile-file-form and then return nil.
       ;; Except that we can't just call byte-compile-file-form since it would
       ;; call us right back.
-      (t (byte-compile-keep-pending form)))))
+      (_ (byte-compile-keep-pending form)))))
 
 (byte-defop-compiler-1 with-no-warnings byte-compile-no-warnings)
 (defun byte-compile-no-warnings (form)
@@ -4518,11 +4577,11 @@ whose definitions have been compiled in this Emacs session, as well as
 all functions called by those functions.
 
 The call graph does not include macros, inline functions, or
-primitives that the byte-code interpreter knows about directly \(eq,
-cons, etc.\).
+primitives that the byte-code interpreter knows about directly
+\(`eq', `cons', etc.).
 
 The call tree also lists those functions which are not known to be called
-\(that is, to which no calls have been compiled\), and which cannot be
+\(that is, to which no calls have been compiled), and which cannot be
 invoked interactively."
   (interactive)
   (message "Generating call tree...")