lisp/emacs-lisp/cl-*.el: Minor changes accumulated during new API design

* lisp/emacs-lisp/cl-macs.el (cl-deftype): Support dispatch on
types that take arguments, as long as they can be used without arguments.

* lisp/emacs-lisp/cl-generic.el (cl--generic-derived-mode-specializers):
Rename from `cl--generic-derived-specializers` to clarify it's about
derived modes and not derived types.
(cl--generic-derived-mode-generalizer): Adjust accordingly and rename
from `cl--generic-derived-generalizer` for the same reason.
Ignore additional args in the tagcode function.
(cl-generic-generalizers) <derived-mode>: Adjust accordingly.

* lisp/emacs-lisp/macroexp.el (macroexp--dynamic-variable-p): Simplify.
This commit is contained in:
David Ponce 2025-10-31 13:34:46 -04:00 committed by Stefan Monnier
parent 13ec843352
commit 1e47f7492a
3 changed files with 38 additions and 12 deletions

View file

@ -1047,7 +1047,7 @@ those methods.")
('cl--generic-eql-generalizer '(eql 'x))
('cl--generic-struct-generalizer 'cl--generic)
('cl--generic-typeof-generalizer 'integer)
('cl--generic-derived-generalizer '(derived-mode c-mode))
('cl--generic-derived-mode-generalizer '(derived-mode c-mode))
('cl--generic-oclosure-generalizer 'oclosure)
(_ x))))
@ -1466,19 +1466,19 @@ This currently works for built-in types and types built on top of records."
;; "&context (major-mode c-mode)" rather than
;; "&context (major-mode (derived-mode c-mode))".
(defun cl--generic-derived-specializers (mode &rest _)
(defun cl--generic-derived-mode-specializers (mode &rest _)
;; FIXME: Handle (derived-mode <mode1> ... <modeN>)
(mapcar (lambda (mode) `(derived-mode ,mode))
(derived-mode-all-parents mode)))
(cl-generic-define-generalizer cl--generic-derived-generalizer
90 (lambda (name) `(and (symbolp ,name) (functionp ,name) ,name))
#'cl--generic-derived-specializers)
(cl-generic-define-generalizer cl--generic-derived-mode-generalizer
90 (lambda (name &rest _) `(and (symbolp ,name) (functionp ,name) ,name))
#'cl--generic-derived-mode-specializers)
(cl-defmethod cl-generic-generalizers ((_specializer (head derived-mode)))
"Support for (derived-mode MODE) specializers.
Used internally for the (major-mode MODE) context specializers."
(list cl--generic-derived-generalizer))
(list cl--generic-derived-mode-generalizer))
(cl-generic-define-context-rewriter major-mode (mode &rest modes)
`(major-mode ,(if (consp mode)

View file

@ -3816,12 +3816,39 @@ If PARENTS is non-nil, ARGLIST must be nil."
(cl-callf (lambda (x) (delq parent-decl x)) (cdr declares))
(when (equal declares '(declare))
(cl-callf (lambda (x) (delq declares x)) decls)))
(and parents arglist
(error "Parents specified, but arglist not empty"))
(let* ((expander
`(cl-function (lambda (&cl-defs ('*) ,@arglist) ,@decls ,@forms)))
;; FIXME: Pass a better lexical context.
(specifier (ignore-errors (funcall (eval expander t))))
`(cl-function
(lambda (&cl-defs ('*) ,@arglist) ,@decls ,@forms)))
(specifier
(condition-case nil
;; FIXME: Pass a better lexical context.
(funcall (eval expander t))
;; We previously signaled an error when the type specified
;; both non-nil parents and arglist, like `unsigned-byte'
;; in below example:
;;
;; (cl-deftype my-integer ()
;; 'integer)
;;
;; (cl-deftype unsigned-byte (&optional bits)
;; "Unsigned integer."
;; (declare (parents my-integer))
;; `(integer 0 ,(if (memq bits '(nil *))
;; bits
;; (1- (ash 1 bits)))))
;;
;; In order to accept the above (correct) definition of
;; `unsigned-byte', call the expander without arguments to
;; check if the arglist is mandatory by catching a
;; `wrong-number-of-arguments' error. If so, and the type
;; specified both parents and arglist, there is a good
;; chance that the type is not atomic, so signal it;
;; otherwise, return nil as previously. Report any other
;; error on type definition.
(wrong-number-of-arguments
(and parents arglist ;; type is not atomic
(error "Type %S with parents may be not atomic: %S"
name arglist)))))
(predicate
(pcase specifier
(`(satisfies ,f) `#',f)

View file

@ -399,7 +399,6 @@ change this."
(defun macroexp--dynamic-variable-p (var)
"Whether the variable VAR is dynamically scoped.
Only valid during macro-expansion."
(defvar byte-compile-bound-variables)
(or (not lexical-binding)
(special-variable-p var)
(memq var macroexp--dynvars)