aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2020-03-10 18:23:41 -0400
committerStefan Monnier2020-03-10 18:23:41 -0400
commit0d6c51320d8066db867aae0e623d9731c69121ed (patch)
tree44c3fa2734b584d3c1fc6b5a8e3f62b61373b994
parentefe85a5b60b016eb3d11829c9590b54d935dd0c6 (diff)
downloademacs-0d6c51320d8066db867aae0e623d9731c69121ed.tar.gz
emacs-0d6c51320d8066db867aae0e623d9731c69121ed.zip
* lisp/emacs-lisp/cl-macs.el: More care with `eval` and with `cl-typep`
(cl-eval-when, cl--compile-time-too, cl-load-time-value): Obey lexical-binding. (cl-check-type): Prefer the predicate rather than the type in the error signal when it's easy to do (as is done outside of CL). (cl-deftype-satisfies): Add definitions for standard types.
-rw-r--r--lisp/emacs-lisp/cl-macs.el57
1 files changed, 37 insertions, 20 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index ef3bc8548d2..954731b06b8 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -75,7 +75,7 @@
75;; one, you may want to amend the other, too. 75;; one, you may want to amend the other, too.
76;;;###autoload 76;;;###autoload
77(define-obsolete-function-alias 'cl--compiler-macro-cXXr 77(define-obsolete-function-alias 'cl--compiler-macro-cXXr
78 'internal--compiler-macro-cXXr "25.1") 78 #'internal--compiler-macro-cXXr "25.1")
79 79
80;;; Some predicates for analyzing Lisp forms. 80;;; Some predicates for analyzing Lisp forms.
81;; These are used by various 81;; These are used by various
@@ -714,9 +714,9 @@ If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level.
714 (let ((comp (or (memq 'compile when) (memq :compile-toplevel when))) 714 (let ((comp (or (memq 'compile when) (memq :compile-toplevel when)))
715 (cl--not-toplevel t)) 715 (cl--not-toplevel t))
716 (if (or (memq 'load when) (memq :load-toplevel when)) 716 (if (or (memq 'load when) (memq :load-toplevel when))
717 (if comp (cons 'progn (mapcar 'cl--compile-time-too body)) 717 (if comp (cons 'progn (mapcar #'cl--compile-time-too body))
718 `(if nil nil ,@body)) 718 `(if nil nil ,@body))
719 (progn (if comp (eval (cons 'progn body))) nil))) 719 (progn (if comp (eval (cons 'progn body) lexical-binding)) nil)))
720 (and (or (memq 'eval when) (memq :execute when)) 720 (and (or (memq 'eval when) (memq :execute when))
721 (cons 'progn body)))) 721 (cons 'progn body))))
722 722
@@ -725,13 +725,13 @@ If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level.
725 (setq form (macroexpand 725 (setq form (macroexpand
726 form (cons '(cl-eval-when) byte-compile-macro-environment)))) 726 form (cons '(cl-eval-when) byte-compile-macro-environment))))
727 (cond ((eq (car-safe form) 'progn) 727 (cond ((eq (car-safe form) 'progn)
728 (cons 'progn (mapcar 'cl--compile-time-too (cdr form)))) 728 (cons 'progn (mapcar #'cl--compile-time-too (cdr form))))
729 ((eq (car-safe form) 'cl-eval-when) 729 ((eq (car-safe form) 'cl-eval-when)
730 (let ((when (nth 1 form))) 730 (let ((when (nth 1 form)))
731 (if (or (memq 'eval when) (memq :execute when)) 731 (if (or (memq 'eval when) (memq :execute when))
732 `(cl-eval-when (compile ,@when) ,@(cddr form)) 732 `(cl-eval-when (compile ,@when) ,@(cddr form))
733 form))) 733 form)))
734 (t (eval form) form))) 734 (t (eval form lexical-binding) form)))
735 735
736;;;###autoload 736;;;###autoload
737(defmacro cl-load-time-value (form &optional _read-only) 737(defmacro cl-load-time-value (form &optional _read-only)
@@ -757,7 +757,7 @@ The result of the body appears to the compiler as a quoted constant."
757 ;; temp is set before we use it. 757 ;; temp is set before we use it.
758 (print set byte-compile--outbuffer)) 758 (print set byte-compile--outbuffer))
759 temp) 759 temp)
760 `',(eval form))) 760 `',(eval form lexical-binding)))
761 761
762 762
763;;; Conditional control structures. 763;;; Conditional control structures.
@@ -1495,8 +1495,8 @@ For more details, see Info node `(cl)Loop Facility'.
1495 (pop cl--loop-args)) 1495 (pop cl--loop-args))
1496 (if (and ands loop-for-bindings) 1496 (if (and ands loop-for-bindings)
1497 (push (nreverse loop-for-bindings) cl--loop-bindings) 1497 (push (nreverse loop-for-bindings) cl--loop-bindings)
1498 (setq cl--loop-bindings (nconc (mapcar 'list loop-for-bindings) 1498 (setq cl--loop-bindings (nconc (mapcar #'list loop-for-bindings)
1499 cl--loop-bindings))) 1499 cl--loop-bindings)))
1500 (if loop-for-sets 1500 (if loop-for-sets
1501 (push `(progn 1501 (push `(progn
1502 ,(cl--loop-let (nreverse loop-for-sets) 'setq ands) 1502 ,(cl--loop-let (nreverse loop-for-sets) 'setq ands)
@@ -1504,7 +1504,7 @@ For more details, see Info node `(cl)Loop Facility'.
1504 cl--loop-body)) 1504 cl--loop-body))
1505 (when loop-for-steps 1505 (when loop-for-steps
1506 (push (cons (if ands 'cl-psetq 'setq) 1506 (push (cons (if ands 'cl-psetq 'setq)
1507 (apply 'append (nreverse loop-for-steps))) 1507 (apply #'append (nreverse loop-for-steps)))
1508 cl--loop-steps)))) 1508 cl--loop-steps))))
1509 1509
1510 ((eq word 'repeat) 1510 ((eq word 'repeat)
@@ -1697,7 +1697,7 @@ If BODY is `setq', then use SPECS for assignments rather than for bindings."
1697 (push binding new)))) 1697 (push binding new))))
1698 (if (eq body 'setq) 1698 (if (eq body 'setq)
1699 (let ((set (cons (if par 'cl-psetq 'setq) 1699 (let ((set (cons (if par 'cl-psetq 'setq)
1700 (apply 'nconc (nreverse new))))) 1700 (apply #'nconc (nreverse new)))))
1701 (if temps `(let* ,(nreverse temps) ,set) set)) 1701 (if temps `(let* ,(nreverse temps) ,set) set))
1702 `(,(if par 'let 'let*) 1702 `(,(if par 'let 'let*)
1703 ,(nconc (nreverse temps) (nreverse new)) ,@body)))) 1703 ,(nconc (nreverse temps) (nreverse new)) ,@body))))
@@ -1823,7 +1823,7 @@ For more details, see `cl-do*' description in Info node `(cl) Iteration'.
1823 (and sets 1823 (and sets
1824 (list (cons (if (or star (not (cdr sets))) 1824 (list (cons (if (or star (not (cdr sets)))
1825 'setq 'cl-psetq) 1825 'setq 'cl-psetq)
1826 (apply 'append sets)))))) 1826 (apply #'append sets))))))
1827 ,@(or (cdr endtest) '(nil))))) 1827 ,@(or (cdr endtest) '(nil)))))
1828 1828
1829;;;###autoload 1829;;;###autoload
@@ -2468,7 +2468,7 @@ Each PLACE may be a symbol, or any generalized variable allowed by `setf'.
2468 2468
2469\(fn PLACE...)" 2469\(fn PLACE...)"
2470 (declare (debug (&rest place))) 2470 (declare (debug (&rest place)))
2471 (if (not (memq nil (mapcar 'symbolp args))) 2471 (if (not (memq nil (mapcar #'symbolp args)))
2472 (and (cdr args) 2472 (and (cdr args)
2473 (let ((sets nil) 2473 (let ((sets nil)
2474 (first (car args))) 2474 (first (car args)))
@@ -3128,13 +3128,27 @@ Of course, we really can't know that for sure, so it's just a heuristic."
3128 (or (cdr (assq sym byte-compile-function-environment)) 3128 (or (cdr (assq sym byte-compile-function-environment))
3129 (cdr (assq sym byte-compile-macro-environment)))))) 3129 (cdr (assq sym byte-compile-macro-environment))))))
3130 3130
3131(put 'null 'cl-deftype-satisfies #'null) 3131(pcase-dolist (`(,type . ,pred)
3132(put 'atom 'cl-deftype-satisfies #'atom) 3132 '((null . null)
3133(put 'real 'cl-deftype-satisfies #'numberp) 3133 (atom . atom)
3134(put 'fixnum 'cl-deftype-satisfies #'integerp) 3134 (real . numberp)
3135(put 'base-char 'cl-deftype-satisfies #'characterp) 3135 (fixnum . integerp)
3136(put 'character 'cl-deftype-satisfies #'natnump) 3136 (base-char . characterp)
3137 3137 (character . natnump)
3138 ;; "Obvious" mappings.
3139 (string . stringp)
3140 (list . listp)
3141 (symbol . symbolp)
3142 (function . functionp)
3143 (integer . integerp)
3144 (float . floatp)
3145 (boolean . booleanp)
3146 (vector . vectorp)
3147 (array . arrayp)
3148 ;; FIXME: Do we really want to consider this a type?
3149 (integer-or-marker . integer-or-marker-p)
3150 ))
3151 (put type 'cl-deftype-satisfies pred))
3138 3152
3139;;;###autoload 3153;;;###autoload
3140(define-inline cl-typep (val type) 3154(define-inline cl-typep (val type)
@@ -3203,7 +3217,10 @@ STRING is an optional description of the desired type."
3203 (macroexp-let2 macroexp-copyable-p temp form 3217 (macroexp-let2 macroexp-copyable-p temp form
3204 `(progn (or (cl-typep ,temp ',type) 3218 `(progn (or (cl-typep ,temp ',type)
3205 (signal 'wrong-type-argument 3219 (signal 'wrong-type-argument
3206 (list ,(or string `',type) ,temp ',form))) 3220 (list ,(or string `',(if (eq 'satisfies
3221 (car-safe type))
3222 (cadr type) type))
3223 ,temp ',form)))
3207 nil)))) 3224 nil))))
3208 3225
3209;;;###autoload 3226;;;###autoload