diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2022-06-06 00:04:00 -0400 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2022-06-06 00:04:00 -0400 |
commit | 5ee4209f307fdf8cde9775539c9596d29edccd6d (patch) | |
tree | d8f806bf4fd46243a82fa04b3add723259743bc4 /lisp/emacs-lisp/cl-macs.el | |
parent | b90d2a6a63f1b7f73d2cb7e976148e8195fc5502 (diff) | |
download | emacs-5ee4209f307fdf8cde9775539c9596d29edccd6d.tar.gz emacs-5ee4209f307fdf8cde9775539c9596d29edccd6d.tar.bz2 emacs-5ee4209f307fdf8cde9775539c9596d29edccd6d.zip |
cl-typep: Emit warning when using a type not known to be a type
`cl-typep` has used a heuristic that if there's a `<foo>-p` function,
then <foo> can be used as a type. This made sense in the past where
most types were not officially declared to be (cl-)types, but nowadays
this just encourages abuses such as using `cl-typecase` with
"types" like `fbound`. It's also a problem for EIEIO objects, where
for historical reasons `<foo>-p` tests if the object is of type
exactly `<foo>` whereas (cl-typep OBJ <foo>) should instead test
if OBJ is a *subtype* of `<foo>`.
So we change `cl-typep` to emit a warning whenever this "-p" heuristic
is used, to discourage abuses, encourage the use of explicit
`cl-deftype` declarations, and try and detect some misuses of
`<foo>-p` for EIEIO objects.
* lisp/emacs-lisp/eieio.el (defclass): Define as type not only at
run-time but also for the current compilation unit.
* lisp/emacs-lisp/eieio-core.el (class, eieio-object): Define as types.
* lisp/emacs-lisp/cl-preloaded.el (cl-struct-define): Don't abuse the
"-p" heuristic.
* lisp/emacs-lisp/cl-macs.el (cl-deftype-satisfies):
Add entries for frames, windows, markers, and overlays.
(cl-typep): Emit a warning when using a predicate that is not known to
correspond to a type.
* lisp/files.el (file-relative-name): Fix error that can trigger if
there's an(other) error between loading `files.el` and loading
`minibuffer.el`.
Diffstat (limited to 'lisp/emacs-lisp/cl-macs.el')
-rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index a9d422929f1..ada4f0344d3 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -3412,19 +3412,23 @@ Of course, we really can't know that for sure, so it's just a heuristic." (cons . consp) (fixnum . fixnump) (float . floatp) + (frame . framep) (function . functionp) (integer . integerp) (keyword . keywordp) (list . listp) + (marker . markerp) (natnum . natnump) (number . numberp) (null . null) + (overlay . overlayp) (real . numberp) (sequence . sequencep) (subr . subrp) (string . stringp) (symbol . symbolp) (vector . vectorp) + (window . windowp) ;; FIXME: Do we really want to consider this a type? (integer-or-marker . integer-or-marker-p) )) @@ -3475,16 +3479,19 @@ Of course, we really can't know that for sure, so it's just a heuristic." (inline-quote (funcall #',(get type 'cl-deftype-satisfies) ,val))) ((and (or 'nil 't) type) (inline-quote ',type)) ((and (pred symbolp) type) - (let* ((name (symbol-name type)) - (namep (intern (concat name "p")))) - (cond - ((cl--macroexp-fboundp namep) (inline-quote (funcall #',namep ,val))) - ((cl--macroexp-fboundp - (setq namep (intern (concat name "-p")))) - (inline-quote (funcall #',namep ,val))) - ((cl--macroexp-fboundp type) (inline-quote (funcall #',type ,val))) - (t (error "Unknown type %S" type))))) - (type (error "Bad type spec: %s" type))))) + (macroexp-warn-and-return + (format-message "Unknown type: %S" type) + (let* ((name (symbol-name type)) + (namep (intern (concat name "p")))) + (cond + ((cl--macroexp-fboundp namep) (inline-quote (funcall #',namep ,val))) + ((cl--macroexp-fboundp + (setq namep (intern (concat name "-p")))) + (inline-quote (funcall #',namep ,val))) + ((cl--macroexp-fboundp type) (inline-quote (funcall #',type ,val))) + (t (error "Unknown type %S" type)))) + nil nil type)) + (type (error "Bad type spec: %S" type))))) ;;;###autoload |