diff options
| author | Stefan Monnier | 2015-03-16 16:11:38 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2015-03-16 16:11:38 -0400 |
| commit | 801eda8a2a00b3f28a69ffe51b05a649fffc5c58 (patch) | |
| tree | 9beec244007c80b46089fd63a2092bf6bcf05238 | |
| parent | f925fc93bac41d7622d1af927e33b0e738ff55b0 (diff) | |
| download | emacs-801eda8a2a00b3f28a69ffe51b05a649fffc5c58.tar.gz emacs-801eda8a2a00b3f28a69ffe51b05a649fffc5c58.zip | |
* lisp/emacs-lisp/cl-macs.el (cl--transform-lambda): Optimize &aux.
Rework to avoid cl--do-arglist in more cases; add comments to explain what's
going on.
(cl--do-&aux): New function extracted from cl--do-arglist.
(cl--do-arglist): Use it.
* lisp/emacs-lisp/cl-generic.el: Add Version: header, for ELPA purposes.
| -rw-r--r-- | lisp/ChangeLog | 7 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-generic.el | 1 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 148 | ||||
| -rw-r--r-- | test/automated/cl-lib-tests.el | 17 |
4 files changed, 124 insertions, 49 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e9e910a8857..41898bee686 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,12 @@ | |||
| 1 | 2015-03-16 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2015-03-16 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * emacs-lisp/cl-macs.el (cl--transform-lambda): Rework to avoid | ||
| 4 | cl--do-arglist in more cases; add comments to explain what's going on. | ||
| 5 | (cl--do-&aux): New function extracted from cl--do-arglist. | ||
| 6 | (cl--do-arglist): Use it. | ||
| 7 | |||
| 8 | * emacs-lisp/cl-generic.el: Add Version: header, for ELPA purposes. | ||
| 9 | |||
| 3 | * obsolete/iswitchb.el (iswitchb-read-buffer): Add `predicate' arg. | 10 | * obsolete/iswitchb.el (iswitchb-read-buffer): Add `predicate' arg. |
| 4 | * isearchb.el (isearchb-iswitchb): Adjust accordingly. | 11 | * isearchb.el (isearchb-iswitchb): Adjust accordingly. |
| 5 | * ido.el (ido-read-buffer): Add `predicate' argument. | 12 | * ido.el (ido-read-buffer): Add `predicate' argument. |
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index a8483ea1355..41c760e960e 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | ;; Copyright (C) 2015 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2015 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Stefan Monnier <monnier@iro.umontreal.ca> | 5 | ;; Author: Stefan Monnier <monnier@iro.umontreal.ca> |
| 6 | ;; Version: 1.0 | ||
| 6 | 7 | ||
| 7 | ;; This file is part of GNU Emacs. | 8 | ;; This file is part of GNU Emacs. |
| 8 | 9 | ||
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 36f263cd20a..712a7485167 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -220,7 +220,20 @@ The name is made by appending a number to PREFIX, default \"G\"." | |||
| 220 | (defconst cl--lambda-list-keywords | 220 | (defconst cl--lambda-list-keywords |
| 221 | '(&optional &rest &key &allow-other-keys &aux &whole &body &environment)) | 221 | '(&optional &rest &key &allow-other-keys &aux &whole &body &environment)) |
| 222 | 222 | ||
| 223 | (defvar cl--bind-block) (defvar cl--bind-defs) (defvar cl--bind-enquote) | 223 | ;; Internal hacks used in formal arg lists: |
| 224 | ;; - &cl-quote: Added to formal-arglists to mean that any default value | ||
| 225 | ;; mentioned in the formal arglist should be considered as implicitly | ||
| 226 | ;; quoted rather than evaluated. This is used in `cl-defsubst' when | ||
| 227 | ;; performing compiler-macro-expansion, since at that time the | ||
| 228 | ;; arguments hold expressions rather than values. | ||
| 229 | ;; - &cl-defs (DEF . DEFS): Gives the default value to use for missing | ||
| 230 | ;; optional arguments which don't have an explicit default value. | ||
| 231 | ;; DEFS is an alist mapping vars to their default default value. | ||
| 232 | ;; and DEF is the default default to use for all other vars. | ||
| 233 | |||
| 234 | (defvar cl--bind-block) ;Name of surrounding block, only use for `signal' data. | ||
| 235 | (defvar cl--bind-defs) ;(DEF . DEFS) giving the "default default" for optargs. | ||
| 236 | (defvar cl--bind-enquote) ;Non-nil if &cl-quote was in the formal arglist! | ||
| 224 | (defvar cl--bind-lets) (defvar cl--bind-forms) | 237 | (defvar cl--bind-lets) (defvar cl--bind-forms) |
| 225 | 238 | ||
| 226 | (defun cl--transform-lambda (form bind-block) | 239 | (defun cl--transform-lambda (form bind-block) |
| @@ -229,19 +242,26 @@ BIND-BLOCK is the name of the symbol to which the function will be bound, | |||
| 229 | and which will be used for the name of the `cl-block' surrounding the | 242 | and which will be used for the name of the `cl-block' surrounding the |
| 230 | function's body. | 243 | function's body. |
| 231 | FORM is of the form (ARGS . BODY)." | 244 | FORM is of the form (ARGS . BODY)." |
| 232 | ;; FIXME: (lambda (a &aux b) 1) expands to (lambda (a &rest --cl-rest--) ...) | ||
| 233 | ;; where the --cl-rest-- is clearly undesired. | ||
| 234 | (let* ((args (car form)) (body (cdr form)) (orig-args args) | 245 | (let* ((args (car form)) (body (cdr form)) (orig-args args) |
| 235 | (cl--bind-block bind-block) (cl--bind-defs nil) (cl--bind-enquote nil) | 246 | (cl--bind-block bind-block) (cl--bind-defs nil) (cl--bind-enquote nil) |
| 236 | (cl--bind-lets nil) (cl--bind-forms nil) | ||
| 237 | (parsed-body (macroexp-parse-body body)) | 247 | (parsed-body (macroexp-parse-body body)) |
| 238 | (header (car parsed-body)) (simple-args nil)) | 248 | (header (car parsed-body)) (simple-args nil)) |
| 239 | (setq body (cdr parsed-body)) | 249 | (setq body (cdr parsed-body)) |
| 250 | ;; "(. X) to (&rest X)" conversion already done in cl--do-arglist, but we | ||
| 251 | ;; do it here as well, so as to be able to see if we can avoid | ||
| 252 | ;; cl--do-arglist. | ||
| 240 | (setq args (if (listp args) (cl-copy-list args) (list '&rest args))) | 253 | (setq args (if (listp args) (cl-copy-list args) (list '&rest args))) |
| 241 | (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) | 254 | (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) |
| 242 | (if (setq cl--bind-defs (cadr (memq '&cl-defs args))) | 255 | (let ((cl-defs (memq '&cl-defs args))) |
| 243 | (setq args (delq '&cl-defs (delq cl--bind-defs args)) | 256 | (when cl-defs |
| 244 | cl--bind-defs (cadr cl--bind-defs))) | 257 | (setq cl--bind-defs (cadr cl-defs)) |
| 258 | ;; Remove "&cl-defs DEFS" from args. | ||
| 259 | (setcdr cl-defs (cddr cl-defs)) | ||
| 260 | (setq args (delq '&cl-defs args)) | ||
| 261 | ;; Optimize away trivial &cl-defs. | ||
| 262 | (if (and (null (car cl--bind-defs)) | ||
| 263 | (cl-every (lambda (x) (null (cadr x))) (cdr cl--bind-defs))) | ||
| 264 | (setq cl--bind-defs nil)))) | ||
| 245 | (if (setq cl--bind-enquote (memq '&cl-quote args)) | 265 | (if (setq cl--bind-enquote (memq '&cl-quote args)) |
| 246 | (setq args (delq '&cl-quote args))) | 266 | (setq args (delq '&cl-quote args))) |
| 247 | (if (memq '&whole args) (error "&whole not currently implemented")) | 267 | (if (memq '&whole args) (error "&whole not currently implemented")) |
| @@ -249,6 +269,9 @@ FORM is of the form (ARGS . BODY)." | |||
| 249 | (v (cadr p))) | 269 | (v (cadr p))) |
| 250 | (if p (setq args (nconc (delq (car p) (delq v args)) | 270 | (if p (setq args (nconc (delq (car p) (delq v args)) |
| 251 | `(&aux (,v macroexpand-all-environment)))))) | 271 | `(&aux (,v macroexpand-all-environment)))))) |
| 272 | ;; Take away all the simple args whose parsing can be handled more | ||
| 273 | ;; efficiently by a plain old `lambda' than the manual parsing generated | ||
| 274 | ;; by `cl--do-arglist'. | ||
| 252 | (while (and args (symbolp (car args)) | 275 | (while (and args (symbolp (car args)) |
| 253 | (not (memq (car args) '(nil &rest &body &key &aux))) | 276 | (not (memq (car args) '(nil &rest &body &key &aux))) |
| 254 | (not (and (eq (car args) '&optional) | 277 | (not (and (eq (car args) '&optional) |
| @@ -256,30 +279,50 @@ FORM is of the form (ARGS . BODY)." | |||
| 256 | (push (pop args) simple-args)) | 279 | (push (pop args) simple-args)) |
| 257 | (or (eq cl--bind-block 'cl-none) | 280 | (or (eq cl--bind-block 'cl-none) |
| 258 | (setq body (list `(cl-block ,cl--bind-block ,@body)))) | 281 | (setq body (list `(cl-block ,cl--bind-block ,@body)))) |
| 259 | (if (null args) | 282 | (let* ((cl--bind-lets nil) (cl--bind-forms nil) |
| 260 | (cl-list* nil (nreverse simple-args) (nconc header body)) | 283 | (rest-args |
| 261 | (if (memq '&optional simple-args) (push '&optional args)) | 284 | (cond |
| 262 | (cl--do-arglist args nil (- (length simple-args) | 285 | ((null args) nil) |
| 263 | (if (memq '&optional simple-args) 1 0))) | 286 | ((eq (car args) '&aux) |
| 264 | (setq cl--bind-lets (nreverse cl--bind-lets)) | 287 | (cl--do-&aux args) |
| 265 | (cl-list* nil | 288 | (setq cl--bind-lets (nreverse cl--bind-lets)) |
| 266 | (nconc (nreverse simple-args) | 289 | nil) |
| 267 | (list '&rest (car (pop cl--bind-lets)))) | 290 | (t ;; `simple-args' doesn't handle all the parsing that we need, |
| 268 | (nconc (save-match-data ;; Macro expansion can take place in the | 291 | ;; so we pass the rest to cl--do-arglist which will do |
| 269 | ;; middle of apparently harmless computation, so it | 292 | ;; "manual" parsing. |
| 270 | ;; should not touch the match-data. | 293 | (let ((slen (length simple-args))) |
| 271 | (require 'help-fns) | 294 | (when (memq '&optional simple-args) |
| 272 | (cons (help-add-fundoc-usage | 295 | (push '&optional args) (cl-decf slen)) |
| 273 | (if (stringp (car header)) (pop header)) | 296 | (setq header |
| 274 | ;; Be careful with make-symbol and (back)quote, | 297 | ;; Macro expansion can take place in the middle of |
| 275 | ;; see bug#12884. | 298 | ;; apparently harmless computation, so it should not |
| 276 | (let ((print-gensym nil) (print-quoted t)) | 299 | ;; touch the match-data. |
| 277 | (format "%S" (cons 'fn (cl--make-usage-args | 300 | (save-match-data |
| 278 | orig-args))))) | 301 | (require 'help-fns) |
| 279 | header)) | 302 | (cons (help-add-fundoc-usage |
| 280 | (list `(let* ,cl--bind-lets | 303 | (if (stringp (car header)) (pop header)) |
| 281 | ,@(nreverse cl--bind-forms) | 304 | ;; Be careful with make-symbol and (back)quote, |
| 282 | ,@body))))))) | 305 | ;; see bug#12884. |
| 306 | (let ((print-gensym nil) (print-quoted t)) | ||
| 307 | (format "%S" (cons 'fn (cl--make-usage-args | ||
| 308 | orig-args))))) | ||
| 309 | header))) | ||
| 310 | ;; FIXME: we'd want to choose an arg name for the &rest param | ||
| 311 | ;; and pass that as `expr' to cl--do-arglist, but that ends up | ||
| 312 | ;; generating code with a redundant let-binding, so we instead | ||
| 313 | ;; pass a dummy and then look in cl--bind-lets to find what var | ||
| 314 | ;; this was bound to. | ||
| 315 | (cl--do-arglist args :dummy slen) | ||
| 316 | (setq cl--bind-lets (nreverse cl--bind-lets)) | ||
| 317 | ;; (cl-assert (eq :dummy (nth 1 (car cl--bind-lets)))) | ||
| 318 | (list '&rest (car (pop cl--bind-lets)))))))) | ||
| 319 | `(nil | ||
| 320 | (,@(nreverse simple-args) ,@rest-args) | ||
| 321 | ,@header | ||
| 322 | ,(macroexp-let* cl--bind-lets | ||
| 323 | (macroexp-progn | ||
| 324 | `(,@(nreverse cl--bind-forms) | ||
| 325 | ,@body))))))) | ||
| 283 | 326 | ||
| 284 | ;;;###autoload | 327 | ;;;###autoload |
| 285 | (defmacro cl-defun (name args &rest body) | 328 | (defmacro cl-defun (name args &rest body) |
| @@ -422,8 +465,7 @@ its argument list allows full Common Lisp conventions." | |||
| 422 | (setcdr last nil) | 465 | (setcdr last nil) |
| 423 | (nconc (cl--make-usage-args arglist) (cl--make-usage-var tail))) | 466 | (nconc (cl--make-usage-args arglist) (cl--make-usage-var tail))) |
| 424 | (setcdr last tail))) | 467 | (setcdr last tail))) |
| 425 | ;; `orig-args' can contain &cl-defs (an internal | 468 | ;; `orig-args' can contain &cl-defs. |
| 426 | ;; CL thingy I don't understand), so remove it. | ||
| 427 | (let ((x (memq '&cl-defs arglist))) | 469 | (let ((x (memq '&cl-defs arglist))) |
| 428 | (when x (setq arglist (delq (car x) (remq (cadr x) arglist))))) | 470 | (when x (setq arglist (delq (car x) (remq (cadr x) arglist))))) |
| 429 | (let ((state nil)) | 471 | (let ((state nil)) |
| @@ -450,6 +492,17 @@ its argument list allows full Common Lisp conventions." | |||
| 450 | )))) | 492 | )))) |
| 451 | arglist)))) | 493 | arglist)))) |
| 452 | 494 | ||
| 495 | (defun cl--do-&aux (args) | ||
| 496 | (while (and (eq (car args) '&aux) (pop args)) | ||
| 497 | (while (and args (not (memq (car args) cl--lambda-list-keywords))) | ||
| 498 | (if (consp (car args)) | ||
| 499 | (if (and cl--bind-enquote (cl-cadar args)) | ||
| 500 | (cl--do-arglist (caar args) | ||
| 501 | `',(cadr (pop args))) | ||
| 502 | (cl--do-arglist (caar args) (cadr (pop args)))) | ||
| 503 | (cl--do-arglist (pop args) nil)))) | ||
| 504 | (if args (error "Malformed argument list ends with: %S" args))) | ||
| 505 | |||
| 453 | (defun cl--do-arglist (args expr &optional num) ; uses cl--bind-* | 506 | (defun cl--do-arglist (args expr &optional num) ; uses cl--bind-* |
| 454 | (if (nlistp args) | 507 | (if (nlistp args) |
| 455 | (if (or (memq args cl--lambda-list-keywords) (not (symbolp args))) | 508 | (if (or (memq args cl--lambda-list-keywords) (not (symbolp args))) |
| @@ -459,8 +512,7 @@ its argument list allows full Common Lisp conventions." | |||
| 459 | (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) | 512 | (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) |
| 460 | (let ((p (memq '&body args))) (if p (setcar p '&rest))) | 513 | (let ((p (memq '&body args))) (if p (setcar p '&rest))) |
| 461 | (if (memq '&environment args) (error "&environment used incorrectly")) | 514 | (if (memq '&environment args) (error "&environment used incorrectly")) |
| 462 | (let ((save-args args) | 515 | (let ((restarg (memq '&rest args)) |
| 463 | (restarg (memq '&rest args)) | ||
| 464 | (safety (if (cl--compiling-file) cl--optimize-safety 3)) | 516 | (safety (if (cl--compiling-file) cl--optimize-safety 3)) |
| 465 | (keys nil) | 517 | (keys nil) |
| 466 | (laterarg nil) (exactarg nil) minarg) | 518 | (laterarg nil) (exactarg nil) minarg) |
| @@ -530,7 +582,12 @@ its argument list allows full Common Lisp conventions." | |||
| 530 | (intern (format ":%s" name))))) | 582 | (intern (format ":%s" name))))) |
| 531 | (varg (if (consp (car arg)) (cl-cadar arg) (car arg))) | 583 | (varg (if (consp (car arg)) (cl-cadar arg) (car arg))) |
| 532 | (def (if (cdr arg) (cadr arg) | 584 | (def (if (cdr arg) (cadr arg) |
| 533 | (or (car cl--bind-defs) (cadr (assq varg cl--bind-defs))))) | 585 | ;; The ordering between those two or clauses is |
| 586 | ;; irrelevant, since in practice only one of the two | ||
| 587 | ;; is ever non-nil (the car is only used for | ||
| 588 | ;; cl-deftype which doesn't use the cdr). | ||
| 589 | (or (car cl--bind-defs) | ||
| 590 | (cadr (assq varg cl--bind-defs))))) | ||
| 534 | (look `(plist-member ,restarg ',karg))) | 591 | (look `(plist-member ,restarg ',karg))) |
| 535 | (and def cl--bind-enquote (setq def `',def)) | 592 | (and def cl--bind-enquote (setq def `',def)) |
| 536 | (if (cddr arg) | 593 | (if (cddr arg) |
| @@ -567,15 +624,8 @@ its argument list allows full Common Lisp conventions." | |||
| 567 | keys) | 624 | keys) |
| 568 | (car ,var))))))) | 625 | (car ,var))))))) |
| 569 | (push `(let ((,var ,restarg)) ,check) cl--bind-forms))) | 626 | (push `(let ((,var ,restarg)) ,check) cl--bind-forms))) |
| 570 | (while (and (eq (car args) '&aux) (pop args)) | 627 | (cl--do-&aux args) |
| 571 | (while (and args (not (memq (car args) cl--lambda-list-keywords))) | 628 | nil))) |
| 572 | (if (consp (car args)) | ||
| 573 | (if (and cl--bind-enquote (cl-cadar args)) | ||
| 574 | (cl--do-arglist (caar args) | ||
| 575 | `',(cadr (pop args))) | ||
| 576 | (cl--do-arglist (caar args) (cadr (pop args)))) | ||
| 577 | (cl--do-arglist (pop args) nil)))) | ||
| 578 | (if args (error "Malformed argument list %s" save-args))))) | ||
| 579 | 629 | ||
| 580 | (defun cl--arglist-args (args) | 630 | (defun cl--arglist-args (args) |
| 581 | (if (nlistp args) (list args) | 631 | (if (nlistp args) (list args) |
| @@ -2608,7 +2658,7 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2608 | (make (cl-mapcar (function (lambda (s d) (if (memq s anames) s d))) | 2658 | (make (cl-mapcar (function (lambda (s d) (if (memq s anames) s d))) |
| 2609 | slots defaults))) | 2659 | slots defaults))) |
| 2610 | (push `(cl-defsubst ,name | 2660 | (push `(cl-defsubst ,name |
| 2611 | (&cl-defs '(nil ,@descs) ,@args) | 2661 | (&cl-defs (nil ,@descs) ,@args) |
| 2612 | ,@(if (cl--safe-expr-p `(progn ,@(mapcar #'cl-second descs))) | 2662 | ,@(if (cl--safe-expr-p `(progn ,@(mapcar #'cl-second descs))) |
| 2613 | '((declare (side-effect-free t)))) | 2663 | '((declare (side-effect-free t)))) |
| 2614 | (,(or type #'vector) ,@make)) | 2664 | (,(or type #'vector) ,@make)) |
| @@ -2716,8 +2766,8 @@ Of course, we really can't know that for sure, so it's just a heuristic." | |||
| 2716 | (t | 2766 | (t |
| 2717 | (inline-quote (or (cl-typep ,val ',head) | 2767 | (inline-quote (or (cl-typep ,val ',head) |
| 2718 | (cl-typep ,val ',rest))))))))) | 2768 | (cl-typep ,val ',rest))))))))) |
| 2719 | (`(member . ,args) | 2769 | (`(eql ,v) (inline-quote (and (eql ,val ',v) t))) |
| 2720 | (inline-quote (and (memql ,val ',args) t))) | 2770 | (`(member . ,args) (inline-quote (and (memql ,val ',args) t))) |
| 2721 | (`(satisfies ,pred) (inline-quote (funcall #',pred ,val))) | 2771 | (`(satisfies ,pred) (inline-quote (funcall #',pred ,val))) |
| 2722 | ((and (pred symbolp) type (guard (get type 'cl-deftype-handler))) | 2772 | ((and (pred symbolp) type (guard (get type 'cl-deftype-handler))) |
| 2723 | (inline-quote | 2773 | (inline-quote |
| @@ -2977,7 +3027,7 @@ The type name can then be used in `cl-typecase', `cl-check-type', etc." | |||
| 2977 | (declare (debug cl-defmacro) (doc-string 3) (indent 2)) | 3027 | (declare (debug cl-defmacro) (doc-string 3) (indent 2)) |
| 2978 | `(cl-eval-when (compile load eval) | 3028 | `(cl-eval-when (compile load eval) |
| 2979 | (put ',name 'cl-deftype-handler | 3029 | (put ',name 'cl-deftype-handler |
| 2980 | (cl-function (lambda (&cl-defs '('*) ,@arglist) ,@body))))) | 3030 | (cl-function (lambda (&cl-defs ('*) ,@arglist) ,@body))))) |
| 2981 | 3031 | ||
| 2982 | (cl-deftype extended-char () `(and character (not base-char))) | 3032 | (cl-deftype extended-char () `(and character (not base-char))) |
| 2983 | 3033 | ||
diff --git a/test/automated/cl-lib-tests.el b/test/automated/cl-lib-tests.el index 1c36e7d7abf..2c188a40059 100644 --- a/test/automated/cl-lib-tests.el +++ b/test/automated/cl-lib-tests.el | |||
| @@ -427,4 +427,21 @@ | |||
| 427 | (ert-deftest cl-flet-test () | 427 | (ert-deftest cl-flet-test () |
| 428 | (should (equal (cl-flet ((f1 (x) x)) (let ((x #'f1)) (funcall x 5))) 5))) | 428 | (should (equal (cl-flet ((f1 (x) x)) (let ((x #'f1)) (funcall x 5))) 5))) |
| 429 | 429 | ||
| 430 | (ert-deftest cl-lib-test-typep () | ||
| 431 | (cl-deftype cl-lib-test-type (&optional x) `(member ,x)) | ||
| 432 | ;; Make sure we correctly implement the rule that deftype's optional args | ||
| 433 | ;; default to `*' rather than to nil. | ||
| 434 | (should (cl-typep '* 'cl-lib-test-type)) | ||
| 435 | (should-not (cl-typep 1 'cl-lib-test-type))) | ||
| 436 | |||
| 437 | (ert-deftest cl-lib-arglist-performance () | ||
| 438 | ;; An `&aux' should not cause lambda's arglist to be turned into an &rest | ||
| 439 | ;; that's parsed by hand. | ||
| 440 | (should (eq () (nth 1 (nth 1 (macroexpand | ||
| 441 | '(cl-function (lambda (&aux (x 1)) x))))))) | ||
| 442 | (cl-defstruct (cl-lib--s (:constructor cl-lib--s-make (&optional a))) a) | ||
| 443 | ;; Similarly the &cl-defs thingy shouldn't cause fallback to manual parsing | ||
| 444 | ;; of args if the default for optional args is nil. | ||
| 445 | (should (equal '(&optional a) (help-function-arglist 'cl-lib--s-make)))) | ||
| 446 | |||
| 430 | ;;; cl-lib.el ends here | 447 | ;;; cl-lib.el ends here |