summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/cl-macs.el
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2022-06-06 00:04:00 -0400
committerStefan Monnier <monnier@iro.umontreal.ca>2022-06-06 00:04:00 -0400
commit5ee4209f307fdf8cde9775539c9596d29edccd6d (patch)
treed8f806bf4fd46243a82fa04b3add723259743bc4 /lisp/emacs-lisp/cl-macs.el
parentb90d2a6a63f1b7f73d2cb7e976148e8195fc5502 (diff)
downloademacs-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.el27
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