* Re: master da8b06bd618 4/4: Merge branch 'lisp-func-type-decls' into 'master'
[not found] ` <20240502150840.D741DC1CB32@vcs2.savannah.gnu.org>
@ 2024-05-09 13:31 ` john muhl
2024-05-10 6:49 ` Andrea Corallo
0 siblings, 1 reply; 3+ messages in thread
From: john muhl @ 2024-05-09 13:31 UTC (permalink / raw)
To: Andrea Corallo; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
This causes some comp-tests to fail here.
make test/src/comp-tests.log
[-- Attachment #2: comp-tests.log --]
[-- Type: text/plain, Size: 16876 bytes --]
Compiling tests...
In comp-test-40187-2-f:
comp-test-funcs.el:292:8: Warning: function `comp-test-40187-2-f' defined multiple times in this file
In comp-test-46824-1-f:
comp-test-funcs.el:508:16: Warning: value from call to `format' is unused
In comp-test-63674-1-f:
comp-test-funcs.el:543:28: Warning: reference to free variable `pkg'
In comp-test-silly-frame2:
comp-test-funcs.el:691:10: Warning: reference to free variable `c'
Loading /home/build/emacs/src/native-lisp/30.0.50-ffd92b4c/comp-test-funcs-21d041cd-3f289e06.eln (native compiled elisp)...
Loading /home/build/emacs/src/native-lisp/30.0.50-ffd92b4c/comp-test-funcs-dyn-3c73ed33-0dcad383.eln (native compiled elisp)...
Running 177 tests (2024-05-02 18:53:38+0300, selector `(not (or (tag :expensive-test) (tag :unstable)))')
passed 1/177 comp-tests-45576-1 (0.000270 sec)
passed 2/177 comp-tests-45635-1 (0.000104 sec)
passed 3/177 comp-tests-46670-1 (0.000147 sec)
passed 4/177 comp-tests-46824-1 (0.000098 sec)
passed 5/177 comp-tests-48029-1 (0.000091 sec)
passed 6/177 comp-tests-61917-1 (0.465415 sec)
passed 7/177 comp-tests-67239-1 (0.000178 sec)
passed 8/177 comp-tests-> (0.000158 sec)
passed 9/177 comp-tests-add1 (0.000146 sec)
passed 10/177 comp-tests-and (0.000132 sec)
passed 11/177 comp-tests-and-3 (0.000158 sec)
passed 12/177 comp-tests-apply (0.000139 sec)
passed 13/177 comp-tests-aref-aset (0.000128 sec)
passed 14/177 comp-tests-arith-comp (0.000150 sec)
passed 15/177 comp-tests-assume-double-neg (0.000129 sec)
passed 16/177 comp-tests-assume-in-loop-1 (0.000129 sec)
passed 17/177 comp-tests-bobp-and-eobp (0.000153 sec)
passed 18/177 comp-tests-bubble-sort (0.014467 sec)
passed 19/177 comp-tests-buffer (0.000182 sec)
passed 20/177 comp-tests-bug-40187 (0.000138 sec)
passed 21/177 comp-tests-bug-42360 (0.000135 sec)
passed 22/177 comp-tests-bug-44968 (0.000369 sec)
passed 23/177 comp-tests-bug-45342 (0.000131 sec)
passed 24/177 comp-tests-bug-45376-1 (0.000128 sec)
passed 25/177 comp-tests-bug-45376-2 (0.000127 sec)
passed 26/177 comp-tests-car-cdr (0.000141 sec)
passed 27/177 comp-tests-car-cdr-safe (0.000134 sec)
passed 28/177 comp-tests-catch (0.000130 sec)
passed 29/177 comp-tests-cl-macro-exp (0.000130 sec)
passed 30/177 comp-tests-cl-uninterned-arg-parse-f (0.000167 sec)
passed 31/177 comp-tests-comp-test-47868-1 (0.000161 sec)
passed 32/177 comp-tests-comp-test-defsubst (0.000153 sec)
passed 33/177 comp-tests-comp-tests-cons-car-cdr (0.000165 sec)
passed 34/177 comp-tests-comp-tests-result-lambda (0.235271 sec)
passed 35/177 comp-tests-compile-forms (0.486876 sec)
passed 36/177 comp-tests-concat (0.000150 sec)
passed 37/177 comp-tests-concatN (0.000127 sec)
passed 38/177 comp-tests-cond-rw-1 (0.000125 sec)
passed 39/177 comp-tests-conditionals (0.000135 sec)
passed 40/177 comp-tests-consp (0.000125 sec)
passed 41/177 comp-tests-copy-insn (0.000129 sec)
passed 42/177 comp-tests-doc (0.000541 sec)
passed 43/177 comp-tests-dynamic-arity (0.000122 sec)
passed 44/177 comp-tests-dynamic-ffuncall (0.000156 sec)
passed 45/177 comp-tests-dynamic-help-arglist (0.000133 sec)
passed 46/177 comp-tests-eq (0.000128 sec)
passed 47/177 comp-tests-ffuncall (0.000170 sec)
passed 48/177 comp-tests-fixnum (0.000149 sec)
passed 49/177 comp-tests-free-fun (0.227816 sec)
passed 50/177 comp-tests-free-fun-silly-name (0.215753 sec)
passed 51/177 comp-tests-free-fun2 (0.234800 sec)
passed 52/177 comp-tests-func-call-removal (0.000203 sec)
passed 53/177 comp-tests-fw-prop-1 (0.226208 sec)
passed 54/177 comp-tests-gc (0.007934 sec)
passed 55/177 comp-tests-if (0.000182 sec)
passed 56/177 comp-tests-integerp (0.000166 sec)
passed 57/177 comp-tests-interactive-form (0.000184 sec)
passed 58/177 comp-tests-jump-table (0.000170 sec)
passed 59/177 comp-tests-lambda-return (0.000163 sec)
passed 60/177 comp-tests-lambda-return2 (0.000160 sec)
passed 61/177 comp-tests-length (0.000160 sec)
passed 62/177 comp-tests-list (0.000287 sec)
passed 63/177 comp-tests-listN (0.000173 sec)
passed 64/177 comp-tests-listp (0.000208 sec)
passed 65/177 comp-tests-macro (0.000206 sec)
passed 66/177 comp-tests-memq (0.000169 sec)
passed 67/177 comp-tests-negate (0.000181 sec)
passed 68/177 comp-tests-non-locals (0.000213 sec)
passed 69/177 comp-tests-not (0.000176 sec)
passed 70/177 comp-tests-not-cons-1 (0.000165 sec)
passed 71/177 comp-tests-num-inline (0.000174 sec)
passed 72/177 comp-tests-numberp (0.000167 sec)
passed 73/177 comp-tests-opt (0.000177 sec)
passed 74/177 comp-tests-opt-rest (0.000181 sec)
passed 75/177 comp-tests-or (0.000168 sec)
passed 76/177 comp-tests-primitive-advice (0.234825 sec)
passed 77/177 comp-tests-primitive-redefine (0.228278 sec)
passed 78/177 comp-tests-primitive-redefine-compile-44221 (0.213895 sec)
passed 79/177 comp-tests-provide (0.000118 sec)
Loading /tmp/test-nativecomp-cache-hYGdCC/30.0.50-ffd92b4c/comp-test-pure-1e49903d-11acdd44.eln (native compiled elisp)...
passed 80/177 comp-tests-pure (0.245152 sec)
passed 81/177 comp-tests-recursive (0.000245 sec)
passed 82/177 comp-tests-ret-type-spec-1 (0.243434 sec)
passed 83/177 comp-tests-ret-type-spec-10 (0.228750 sec)
passed 84/177 comp-tests-ret-type-spec-11 (0.272693 sec)
passed 85/177 comp-tests-ret-type-spec-12 (0.253554 sec)
Test comp-tests-ret-type-spec-13 backtrace:
signal(ert-test-failed (((should (comp-tests--types-equal (cl-third
ert-fail(((should (comp-tests--types-equal (cl-third (subr-type (sym
comp-tests-check-ret-type-spec((defun comp-tests-ret-type-spec-f (x
#f(compiled-function () #<bytecode -0x10afcaca55175f08>)()
#f(compiled-function () #<bytecode 0xffa4baccb80b4ed>)()
handler-bind-1(#f(compiled-function () #<bytecode 0xffa4baccb80b4ed>
ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
ert-run-test(#s(ert-test :name comp-tests-ret-type-spec-13 :document
ert-run-or-rerun-test(#s(ert--stats :selector ... :tests ... :test-m
ert-run-tests((not (or (tag :expensive-test) (tag :unstable))) #f(co
ert-run-tests-batch((not (or (tag :expensive-test) (tag :unstable)))
ert-run-tests-batch-and-exit((not (or (tag :expensive-test) (tag :un
eval((ert-run-tests-batch-and-exit '(not (or (tag :expensive-test) (
command-line-1(("-L" ":." "-l" "ert" "--eval" "(setq treesit-extra-l
command-line()
normal-top-level()
Test comp-tests-ret-type-spec-13 condition:
(ert-test-failed
((should (comp-tests--types-equal (cl-third ...) ret-type)) :form
(comp-tests--types-equal t (or (member foo) number-or-marker))
:value nil))
FAILED 86/177 comp-tests-ret-type-spec-13 (0.236345 sec) at src/comp-tests.el:1
passed 87/177 comp-tests-ret-type-spec-14 (0.224512 sec)
passed 88/177 comp-tests-ret-type-spec-15 (0.252019 sec)
passed 89/177 comp-tests-ret-type-spec-16 (0.223034 sec)
Warning: Unused lexical variable `x'
passed 90/177 comp-tests-ret-type-spec-17 (0.238949 sec)
passed 91/177 comp-tests-ret-type-spec-18 (0.212300 sec)
Test comp-tests-ret-type-spec-19 backtrace:
signal(ert-test-failed (((should (comp-tests--types-equal (cl-third
ert-fail(((should (comp-tests--types-equal (cl-third (subr-type (sym
comp-tests-check-ret-type-spec((defun comp-tests-ret-type-spec-f (x
#f(compiled-function () #<bytecode -0x10afcaca55175c16>)()
#f(compiled-function () #<bytecode 0xffa4baccb80b4ed>)()
handler-bind-1(#f(compiled-function () #<bytecode 0xffa4baccb80b4ed>
ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
ert-run-test(#s(ert-test :name comp-tests-ret-type-spec-19 :document
ert-run-or-rerun-test(#s(ert--stats :selector ... :tests ... :test-m
ert-run-tests((not (or (tag :expensive-test) (tag :unstable))) #f(co
ert-run-tests-batch((not (or (tag :expensive-test) (tag :unstable)))
ert-run-tests-batch-and-exit((not (or (tag :expensive-test) (tag :un
eval((ert-run-tests-batch-and-exit '(not (or (tag :expensive-test) (
command-line-1(("-L" ":." "-l" "ert" "--eval" "(setq treesit-extra-l
command-line()
normal-top-level()
Test comp-tests-ret-type-spec-19 condition:
(ert-test-failed
((should (comp-tests--types-equal (cl-third ...) ret-type)) :form
(comp-tests--types-equal t boolean) :value nil))
FAILED 92/177 comp-tests-ret-type-spec-19 (0.210587 sec) at src/comp-tests.el:1
passed 93/177 comp-tests-ret-type-spec-2 (0.202012 sec)
passed 94/177 comp-tests-ret-type-spec-20 (0.225417 sec)
passed 95/177 comp-tests-ret-type-spec-21 (0.243111 sec)
passed 96/177 comp-tests-ret-type-spec-22 (0.248258 sec)
passed 97/177 comp-tests-ret-type-spec-23 (0.236634 sec)
passed 98/177 comp-tests-ret-type-spec-24 (0.239766 sec)
passed 99/177 comp-tests-ret-type-spec-25 (0.241657 sec)
passed 100/177 comp-tests-ret-type-spec-26 (0.244272 sec)
passed 101/177 comp-tests-ret-type-spec-27 (0.272538 sec)
passed 102/177 comp-tests-ret-type-spec-28 (0.293280 sec)
passed 103/177 comp-tests-ret-type-spec-29 (0.225819 sec)
passed 104/177 comp-tests-ret-type-spec-3 (0.270763 sec)
passed 105/177 comp-tests-ret-type-spec-30 (0.218054 sec)
passed 106/177 comp-tests-ret-type-spec-31 (0.248969 sec)
passed 107/177 comp-tests-ret-type-spec-32 (0.252188 sec)
passed 108/177 comp-tests-ret-type-spec-33 (0.228778 sec)
passed 109/177 comp-tests-ret-type-spec-34 (0.224584 sec)
Test comp-tests-ret-type-spec-35 backtrace:
signal(ert-test-failed (((should (comp-tests--types-equal (cl-third
ert-fail(((should (comp-tests--types-equal (cl-third (subr-type (sym
comp-tests-check-ret-type-spec((defun comp-tests-ret-type-spec-f (x)
#f(compiled-function () #<bytecode -0x10afcaca55147ccc>)()
#f(compiled-function () #<bytecode 0xffa4baccb80b4ed>)()
handler-bind-1(#f(compiled-function () #<bytecode 0xffa4baccb80b4ed>
ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
ert-run-test(#s(ert-test :name comp-tests-ret-type-spec-35 :document
ert-run-or-rerun-test(#s(ert--stats :selector ... :tests ... :test-m
ert-run-tests((not (or (tag :expensive-test) (tag :unstable))) #f(co
ert-run-tests-batch((not (or (tag :expensive-test) (tag :unstable)))
ert-run-tests-batch-and-exit((not (or (tag :expensive-test) (tag :un
eval((ert-run-tests-batch-and-exit '(not (or (tag :expensive-test) (
command-line-1(("-L" ":." "-l" "ert" "--eval" "(setq treesit-extra-l
command-line()
normal-top-level()
Test comp-tests-ret-type-spec-35 condition:
(ert-test-failed
((should (comp-tests--types-equal (cl-third ...) ret-type)) :form
(comp-tests--types-equal t (or null number-or-marker)) :value nil))
FAILED 110/177 comp-tests-ret-type-spec-35 (0.233763 sec) at src/comp-tests.el:1
passed 111/177 comp-tests-ret-type-spec-36 (0.232922 sec)
passed 112/177 comp-tests-ret-type-spec-37 (0.224470 sec)
passed 113/177 comp-tests-ret-type-spec-38 (0.273395 sec)
passed 114/177 comp-tests-ret-type-spec-39 (0.248476 sec)
passed 115/177 comp-tests-ret-type-spec-4 (0.244463 sec)
passed 116/177 comp-tests-ret-type-spec-40 (0.236998 sec)
passed 117/177 comp-tests-ret-type-spec-41 (0.240048 sec)
passed 118/177 comp-tests-ret-type-spec-42 (0.321033 sec)
passed 119/177 comp-tests-ret-type-spec-43 (0.333541 sec)
passed 120/177 comp-tests-ret-type-spec-44 (0.285091 sec)
passed 121/177 comp-tests-ret-type-spec-45 (0.291836 sec)
passed 122/177 comp-tests-ret-type-spec-46 (0.294387 sec)
passed 123/177 comp-tests-ret-type-spec-47 (0.230879 sec)
passed 124/177 comp-tests-ret-type-spec-48 (0.282248 sec)
passed 125/177 comp-tests-ret-type-spec-49 (0.244847 sec)
passed 126/177 comp-tests-ret-type-spec-5 (0.230772 sec)
passed 127/177 comp-tests-ret-type-spec-50 (0.225838 sec)
passed 128/177 comp-tests-ret-type-spec-51 (0.223122 sec)
passed 129/177 comp-tests-ret-type-spec-52 (0.249659 sec)
passed 130/177 comp-tests-ret-type-spec-53 (0.238974 sec)
passed 131/177 comp-tests-ret-type-spec-54 (0.268240 sec)
passed 132/177 comp-tests-ret-type-spec-55 (0.263748 sec)
passed 133/177 comp-tests-ret-type-spec-56 (0.274669 sec)
passed 134/177 comp-tests-ret-type-spec-57 (0.222864 sec)
passed 135/177 comp-tests-ret-type-spec-58 (0.243958 sec)
passed 136/177 comp-tests-ret-type-spec-59 (0.254253 sec)
Test comp-tests-ret-type-spec-6 backtrace:
signal(ert-test-failed (((should (comp-tests--types-equal (cl-third
ert-fail(((should (comp-tests--types-equal (cl-third (subr-type (sym
comp-tests-check-ret-type-spec((defun comp-tests-ret-type-spec-f (x)
#f(compiled-function () #<bytecode -0x10afcaca55175e72>)()
#f(compiled-function () #<bytecode 0xffa4baccb80b4ed>)()
handler-bind-1(#f(compiled-function () #<bytecode 0xffa4baccb80b4ed>
ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
ert-run-test(#s(ert-test :name comp-tests-ret-type-spec-6 :documenta
ert-run-or-rerun-test(#s(ert--stats :selector ... :tests ... :test-m
ert-run-tests((not (or (tag :expensive-test) (tag :unstable))) #f(co
ert-run-tests-batch((not (or (tag :expensive-test) (tag :unstable)))
ert-run-tests-batch-and-exit((not (or (tag :expensive-test) (tag :un
eval((ert-run-tests-batch-and-exit '(not (or (tag :expensive-test) (
command-line-1(("-L" ":." "-l" "ert" "--eval" "(setq treesit-extra-l
command-line()
normal-top-level()
Test comp-tests-ret-type-spec-6 condition:
(ert-test-failed
((should (comp-tests--types-equal (cl-third ...) ret-type)) :form
(comp-tests--types-equal t (or cons (integer 3 3))) :value nil))
FAILED 137/177 comp-tests-ret-type-spec-6 (0.258427 sec) at src/comp-tests.el:1
passed 138/177 comp-tests-ret-type-spec-60 (0.259341 sec)
passed 139/177 comp-tests-ret-type-spec-61 (0.279411 sec)
passed 140/177 comp-tests-ret-type-spec-62 (0.276835 sec)
passed 141/177 comp-tests-ret-type-spec-63 (0.298703 sec)
passed 142/177 comp-tests-ret-type-spec-64 (0.247217 sec)
passed 143/177 comp-tests-ret-type-spec-65 (0.259782 sec)
passed 144/177 comp-tests-ret-type-spec-66 (0.283321 sec)
passed 145/177 comp-tests-ret-type-spec-67 (0.241593 sec)
passed 146/177 comp-tests-ret-type-spec-68 (0.230272 sec)
passed 147/177 comp-tests-ret-type-spec-69 (0.217810 sec)
passed 148/177 comp-tests-ret-type-spec-7 (0.210312 sec)
passed 149/177 comp-tests-ret-type-spec-70 (0.245089 sec)
passed 150/177 comp-tests-ret-type-spec-71 (0.274714 sec)
passed 151/177 comp-tests-ret-type-spec-72 (0.258018 sec)
passed 152/177 comp-tests-ret-type-spec-73 (0.236202 sec)
passed 153/177 comp-tests-ret-type-spec-74 (0.246754 sec)
passed 154/177 comp-tests-ret-type-spec-75 (0.255554 sec)
passed 155/177 comp-tests-ret-type-spec-76 (0.255281 sec)
passed 156/177 comp-tests-ret-type-spec-77 (0.235663 sec)
passed 157/177 comp-tests-ret-type-spec-78 (0.238891 sec)
passed 158/177 comp-tests-ret-type-spec-79 (0.313786 sec)
passed 159/177 comp-tests-ret-type-spec-8 (0.236469 sec)
passed 160/177 comp-tests-ret-type-spec-80 (0.222464 sec)
passed 161/177 comp-tests-ret-type-spec-9 (0.233859 sec)
passed 162/177 comp-tests-save-excursion (0.000147 sec)
passed 163/177 comp-tests-setcarcdr (0.000123 sec)
passed 164/177 comp-tests-signal (0.000108 sec)
passed 165/177 comp-tests-speed--1 (0.000111 sec)
passed 166/177 comp-tests-stack (0.000130 sec)
passed 167/177 comp-tests-string-trim (0.000120 sec)
passed 168/177 comp-tests-stringp (0.000109 sec)
passed 169/177 comp-tests-sub1 (0.000111 sec)
passed 170/177 comp-tests-symbol-value (0.000105 sec)
passed 171/177 comp-tests-symbolp (0.000107 sec)
passed 172/177 comp-tests-tco (0.241300 sec)
passed 173/177 comp-tests-trampoline-removal (0.000144 sec)
passed 174/177 comp-tests-type-hints (0.000122 sec)
passed 175/177 comp-tests-unwind-protect (0.000127 sec)
passed 176/177 comp-tests-varref (0.000118 sec)
passed 177/177 comp-tests-varset (0.000117 sec)
Ran 177 tests, 173 results as expected, 4 unexpected (2024-05-02 18:54:02+0300, 23.792607 sec)
4 unexpected results:
FAILED comp-tests-ret-type-spec-13
FAILED comp-tests-ret-type-spec-19
FAILED comp-tests-ret-type-spec-35
FAILED comp-tests-ret-type-spec-6
[-- Attachment #3: Type: text/plain, Size: 31686 bytes --]
Andrea Corallo <acorallo@gnu.org> writes:
> branch: master
> commit da8b06bd6181bc56fb0f133d17cae7eff44a83e8
> Merge: 2f5c9b31161 64d3100cb59
> Author: Andrea Corallo <acorallo@gnu.org>
> Commit: Andrea Corallo <acorallo@gnu.org>
>
> Merge branch 'lisp-func-type-decls' into 'master'
> ---
> doc/lispref/functions.texi | 52 ++++++++++++++++++++++++++++++++++
> etc/NEWS | 5 ++++
> lisp/custom.el | 3 +-
> lisp/emacs-lisp/byte-run.el | 8 +++++-
> lisp/emacs-lisp/comp-common.el | 64 +++++++++++++-----------------------------
> lisp/emacs-lisp/comp.el | 24 +++++++++++-----
> lisp/emacs-lisp/lisp.el | 3 +-
> lisp/emacs-lisp/regexp-opt.el | 3 +-
> lisp/env.el | 3 +-
> lisp/files.el | 1 +
> lisp/help-fns.el | 2 +-
> lisp/simple.el | 10 +++++--
> lisp/subr.el | 36 ++++++++++++++++--------
> lisp/window.el | 9 ++++--
> 14 files changed, 147 insertions(+), 76 deletions(-)
>
> diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
> index c57de08460f..d88f5d05339 100644
> --- a/doc/lispref/functions.texi
> +++ b/doc/lispref/functions.texi
> @@ -2709,6 +2709,58 @@ native code emitted for the function. In particular, if @var{n} is
> @minus{}1, native compilation of the function will emit bytecode
> instead of native code for the function.
>
> +@item (type @var{type})
> +Declare @var{type} to be the type of this function. This is used for
> +documentation by @code{describe-function}. Also it can be used by the
> +native compiler (@pxref{Native Compilation}) for improving code
> +generation and for deriving more precisely the type of other functions
> +without type declaration.
> +
> +@var{type} is a type specifier in the form @w{@code{(function
> +(ARG-1-TYPE ... ARG-N-TYPE) RETURN-TYPE)}}. Argument types can be
> +interleaved with symbols @code{&optional} and @code{&rest} to match the
> +function's arguments (@pxref{Argument List}).
> +
> +Here's an example of using @code{type} inside @code{declare} to declare
> +a function @code{positive-p} that takes an argument of type @var{number}
> +and return a @var{boolean}:
> +
> +@group
> +@lisp
> +(defun positive-p (x)
> + (declare (type (function (number) boolean)))
> + (when (> x 0)
> + t))
> +@end lisp
> +@end group
> +
> +Similarly this declares a function @code{cons-or-number} that: expects a
> +first argument being a @var{cons} or a @var{number}, a second optional
> +argument of type @var{string} and return one of the symbols
> +@code{is-cons} or @code{is-number}:
> +
> +@group
> +@lisp
> +(defun cons-or-number (x &optional err-msg)
> + (declare (type (function ((or cons number) &optional string)
> + (member is-cons is-number))))
> + (if (consp x)
> + 'is-cons
> + (if (numberp x)
> + 'is-number
> + (error (or err-msg "Unexpected input")))))
> +@end lisp
> +@end group
> +
> +More types are described in the Lisp Data Types chapter (@ref{Lisp Data
> +Types}).
> +
> +Declaring a function with an incorrect type produces undefined behavior
> +and could lead to unexpected results or might even crash Emacs when code
> +is native-compiled and loaded. Note also that when redefining (or
> +advising) a type declared function the replacement should respect the
> +original signature to avoid undefined behavior.
> +
> @item no-font-lock-keyword
> This is valid for macros only. Macros with this declaration are
> highlighted by font-lock (@pxref{Font Lock Mode}) as normal functions,
> diff --git a/etc/NEWS b/etc/NEWS
> index 4d363d300a8..8477a1eed58 100644
> --- a/etc/NEWS
> +++ b/etc/NEWS
> @@ -1939,6 +1939,11 @@ unibyte string.
> \f
> * Lisp Changes in Emacs 30.1
>
> ++++
> +** Function type declaration
> +It is now possible, using the 'declare' macro, to declare expected types
> +of function arguments and return type.
> +
> ** New types 'closure' and 'interpreted-function'.
> 'interpreted-function' is the new type used for interpreted functions,
> and 'closure' is the common parent type of 'interpreted-function'
> diff --git a/lisp/custom.el b/lisp/custom.el
> index a19b14aaf8a..6f2aa18ba1d 100644
> --- a/lisp/custom.el
> +++ b/lisp/custom.el
> @@ -667,7 +667,8 @@ If NOSET is non-nil, don't bother autoloading LOAD when setting the variable."
> A customizable variable is either (i) a variable whose property
> list contains a non-nil `standard-value' or `custom-autoload'
> property, or (ii) an alias for another customizable variable."
> - (declare (side-effect-free t))
> + (declare (type (function (symbol) t))
> + (side-effect-free t))
> (when (symbolp variable)
> (setq variable (indirect-variable variable))
> (or (get variable 'standard-value)
> diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el
> index cc176821026..84cc83f2270 100644
> --- a/lisp/emacs-lisp/byte-run.el
> +++ b/lisp/emacs-lisp/byte-run.el
> @@ -217,6 +217,11 @@ So far, FUNCTION can only be a symbol, not a lambda expression."
> (cadr elem)))
> val)))))
>
> +(defalias 'byte-run--set-function-type
> + #'(lambda (f _args &rest val)
> + (list 'function-put (list 'quote f)
> + ''function-type (list 'quote val))))
> +
> ;; Add any new entries to info node `(elisp)Declare Form'.
> (defvar defun-declarations-alist
> (list
> @@ -239,7 +244,8 @@ If `error-free', drop calls even if `byte-compile-delete-errors' is nil.")
> (list 'speed #'byte-run--set-speed)
> (list 'completion #'byte-run--set-completion)
> (list 'modes #'byte-run--set-modes)
> - (list 'interactive-args #'byte-run--set-interactive-args))
> + (list 'interactive-args #'byte-run--set-interactive-args)
> + (list 'type #'byte-run--set-function-type))
> "List associating function properties to their macro expansion.
> Each element of the list takes the form (PROP FUN) where FUN is
> a function. For each (PROP . VALUES) in a function's declaration,
> diff --git a/lisp/emacs-lisp/comp-common.el b/lisp/emacs-lisp/comp-common.el
> index 62fd28f772e..ef40882a98a 100644
> --- a/lisp/emacs-lisp/comp-common.el
> +++ b/lisp/emacs-lisp/comp-common.el
> @@ -68,7 +68,7 @@ Used to modify the compiler environment."
> :risky t
> :version "28.1")
>
> -(defconst comp-known-type-specifiers
> +(defconst comp-primitive-type-specifiers
> `(
> ;; Functions we can trust not to be redefined, or, if redefined,
> ;; to expose the same type. The vast majority of these are
> @@ -97,7 +97,6 @@ Used to modify the compiler environment."
> (assq (function (t list) list))
> (atan (function (number &optional number) float))
> (atom (function (t) boolean))
> - (bignump (function (t) boolean))
> (bobp (function () boolean))
> (bolp (function () boolean))
> (bool-vector-count-consecutive
> @@ -107,7 +106,6 @@ Used to modify the compiler environment."
> (bool-vector-p (function (t) boolean))
> (bool-vector-subsetp (function (bool-vector bool-vector) boolean))
> (boundp (function (symbol) boolean))
> - (buffer-end (function ((or number marker)) integer))
> (buffer-file-name (function (&optional buffer) (or string null)))
> (buffer-list (function (&optional frame) list))
> (buffer-local-variables (function (&optional buffer) list))
> @@ -157,8 +155,6 @@ Used to modify the compiler environment."
> (copy-sequence (function (sequence) sequence))
> (copysign (function (float float) float))
> (cos (function (number) float))
> - (count-lines
> - (function ((or integer marker) (or integer marker) &optional t) integer))
> (current-buffer (function () buffer))
> (current-global-map (function () cons))
> (current-indentation (function () integer))
> @@ -171,7 +167,6 @@ Used to modify the compiler environment."
> (current-time-zone (function (&optional (or number list)
> (or symbol string cons integer))
> cons))
> - (custom-variable-p (function (symbol) t))
> (decode-char (function (cons t) (or fixnum null)))
> (decode-time (function (&optional (or number list)
> (or symbol string cons integer)
> @@ -179,7 +174,6 @@ Used to modify the compiler environment."
> cons))
> (default-boundp (function (symbol) boolean))
> (default-value (function (symbol) t))
> - (degrees-to-radians (function (number) float))
> (documentation
> (function ((or function symbol subr) &optional t) (or null string)))
> (downcase (function ((or fixnum string)) (or fixnum string)))
> @@ -192,7 +186,6 @@ Used to modify the compiler environment."
> (eql (function (t t) boolean))
> (equal (function (t t) boolean))
> (error-message-string (function (list) string))
> - (eventp (function (t) boolean))
> (exp (function (number) float))
> (expt (function (number number) number))
> (fboundp (function (symbol) boolean))
> @@ -207,7 +200,6 @@ Used to modify the compiler environment."
> (file-readable-p (function (string) boolean))
> (file-symlink-p (function (string) (or boolean string)))
> (file-writable-p (function (string) boolean))
> - (fixnump (function (t) boolean))
> (float (function (number) float))
> (float-time (function (&optional (or number list)) float))
> (floatp (function (t) boolean))
> @@ -230,18 +222,12 @@ Used to modify the compiler environment."
> (function (&optional (or buffer string) (or symbol (integer 0 0)))
> (or null window)))
> (get-file-buffer (function (string) (or null buffer)))
> - (get-largest-window (function (&optional t t t) (or window null)))
> - (get-lru-window (function (&optional t t t) (or window null)))
> - (getenv (function (string &optional frame) (or null string)))
> (gethash (function (t hash-table &optional t) t))
> (hash-table-count (function (hash-table) integer))
> (hash-table-p (function (t) boolean))
> (identity (function (t) t))
> - (ignore (function (&rest t) null))
> - (int-to-string (function (number) string))
> (integer-or-marker-p (function (t) boolean))
> (integerp (function (t) boolean))
> - (interactive-p (function () boolean))
> (intern-soft (function ((or string symbol) &optional (or obarray vector))
> symbol))
> (invocation-directory (function () string))
> @@ -250,8 +236,6 @@ Used to modify the compiler environment."
> (keymap-parent (function (cons) (or cons null)))
> (keymapp (function (t) boolean))
> (keywordp (function (t) boolean))
> - (last (function (list &optional integer) list))
> - (lax-plist-get (function (list t) t))
> (ldexp (function (number integer) float))
> (length (function (t) (integer 0 *)))
> (length< (function (sequence fixnum) boolean))
> @@ -265,7 +249,6 @@ Used to modify the compiler environment."
> (local-variable-p (function (symbol &optional buffer) boolean))
> (locale-info (function ((member codeset days months paper)) (or null string)))
> (log (function (number number) float))
> - (log10 (function (number) float))
> (logand (function (&rest (or integer marker)) integer))
> (logb (function (number) integer))
> (logcount (function (integer) integer))
> @@ -273,7 +256,6 @@ Used to modify the compiler environment."
> (lognot (function (integer) integer))
> (logxor (function (&rest (or integer marker)) integer))
> ;; (lsh (function ((integer ,most-negative-fixnum *) integer) integer)) ?
> - (lsh (function (integer integer) integer))
> (make-byte-code
> (function ((or fixnum list) string vector integer &optional string t
> &rest t)
> @@ -282,14 +264,12 @@ Used to modify the compiler environment."
> (make-marker (function () marker))
> (make-string (function (integer fixnum &optional t) string))
> (make-symbol (function (string) symbol))
> - (mark (function (&optional t) (or integer null)))
> (mark-marker (function () marker))
> (marker-buffer (function (marker) (or buffer null)))
> (markerp (function (t) boolean))
> (max (function ((or number marker) &rest (or number marker)) number))
> (max-char (function (&optional t) fixnum))
> (member (function (t list) list))
> - (memory-limit (function () integer))
> (memq (function (t list) list))
> (memql (function (t list) list))
> (min (function ((or number marker) &rest (or number marker)) number))
> @@ -298,7 +278,6 @@ Used to modify the compiler environment."
> (mod
> (function ((or number marker) (or number marker))
> (or (integer 0 *) (float 0 *))))
> - (mouse-movement-p (function (t) boolean))
> (multibyte-char-to-unibyte (function (fixnum) fixnum))
> (natnump (function (t) boolean))
> (next-window (function (&optional window t t) window))
> @@ -310,9 +289,7 @@ Used to modify the compiler environment."
> (number-or-marker-p (function (t) boolean))
> (number-to-string (function (number) string))
> (numberp (function (t) boolean))
> - (one-window-p (function (&optional t t) boolean))
> (overlayp (function (t) boolean))
> - (parse-colon-path (function (string) list))
> (plist-get (function (list t &optional t) t))
> (plist-member (function (list t &optional t) list))
> (point (function () integer))
> @@ -325,13 +302,11 @@ Used to modify the compiler environment."
> (processp (function (t) boolean))
> (proper-list-p (function (t) (or fixnum null)))
> (propertize (function (string &rest t) string))
> - (radians-to-degrees (function (number) float))
> (rassoc (function (t list) list))
> (rassq (function (t list) list))
> (read-from-string (function (string &optional integer integer) cons))
> (recent-keys (function (&optional (or cons null)) vector))
> (recursion-depth (function () integer))
> - (regexp-opt (function (list) string))
> (regexp-quote (function (string) string))
> (region-beginning (function () integer))
> (region-end (function () integer))
> @@ -387,7 +362,6 @@ Used to modify the compiler environment."
> (upcase (function ((or fixnum string)) (or fixnum string)))
> (user-full-name (function (&optional integer) (or string null)))
> (user-login-name (function (&optional integer) (or string null)))
> - (user-original-login-name (function (&optional integer) (or string null)))
> (user-real-login-name (function () string))
> (user-real-uid (function () integer))
> (user-uid (function () integer))
> @@ -400,13 +374,8 @@ Used to modify the compiler environment."
> (window-live-p (function (t) boolean))
> (window-valid-p (function (t) boolean))
> (windowp (function (t) boolean))
> - (zerop (function (number) boolean))
> - ;; Type hints
> - (comp-hint-fixnum (function (t) fixnum))
> - (comp-hint-cons (function (t) cons))
> ;; Non returning functions
> (throw (function (t t) nil))
> - (error (function (string &rest t) nil))
> (signal (function (symbol t) nil)))
> "Alist used for type propagation.")
>
> @@ -532,22 +501,27 @@ Account for `native-comp-eln-load-path' and `comp-native-version-dir'."
> (defun comp-function-type-spec (function)
> "Return the type specifier of FUNCTION.
>
> -This function returns a cons cell whose car is the function
> -specifier, and cdr is a symbol, either `inferred' or `know'.
> -If the symbol is `inferred', the type specifier is automatically
> -inferred from the code itself by the native compiler; if it is
> -`know', the type specifier comes from `comp-known-type-specifiers'."
> - (let ((kind 'know)
> - type-spec )
> - (when-let ((res (assoc function comp-known-type-specifiers)))
> +This function returns a cons cell whose car is the function specifier,
> +and cdr is a symbol, either `inferred' or `declared'. If the symbol is
> +`inferred', the type specifier is automatically inferred from the code
> +itself by the native compiler; if it is `declared', the type specifier
> +comes from `comp-primitive-type-specifiers' or the function type declaration
> +itself."
> + (let ((kind 'declared)
> + type-spec)
> + (when-let ((res (assoc function comp-primitive-type-specifiers)))
> + ;; Declared primitive
> (setf type-spec (cadr res)))
> (let ((f (and (symbolp function)
> (symbol-function function))))
> - (when (and f
> - (null type-spec)
> - (subr-native-elisp-p f))
> - (setf kind 'inferred
> - type-spec (subr-type f))))
> + (when (and f (null type-spec))
> + (if-let ((delc-type (function-get function 'function-type)))
> + ;; Declared Lisp function
> + (setf type-spec (car delc-type))
> + (when (subr-native-elisp-p f)
> + ;; Native compiled inferred
> + (setf kind 'inferred
> + type-spec (subr-type f))))))
> (when type-spec
> (cons type-spec kind))))
>
> diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
> index 2ec55ed98ee..d7cd6b79c86 100644
> --- a/lisp/emacs-lisp/comp.el
> +++ b/lisp/emacs-lisp/comp.el
> @@ -179,16 +179,24 @@ For internal use by the test suite only.")
> Each function in FUNCTIONS is run after PASS.
> Useful to hook into pass checkers.")
>
> -(defconst comp-known-func-cstr-h
> +(defconst comp-primitive-func-cstr-h
> (cl-loop
> with comp-ctxt = (make-comp-cstr-ctxt)
> with h = (make-hash-table :test #'eq)
> - for (f type-spec) in comp-known-type-specifiers
> + for (f type-spec) in comp-primitive-type-specifiers
> for cstr = (comp-type-spec-to-cstr type-spec)
> do (puthash f cstr h)
> finally return h)
> "Hash table function -> `comp-constraint'.")
>
> +(defun comp--get-function-cstr (function)
> + "Given FUNCTION return the corresponding `comp-constraint'."
> + (when (symbolp function)
> + (let ((f (symbol-function function)))
> + (or (gethash f comp-primitive-func-cstr-h)
> + (when-let ((res (function-get function 'function-type)))
> + (comp-type-spec-to-cstr (car res)))))))
> +
> ;; Keep it in sync with the `cl-deftype-satisfies' property set in
> ;; cl-macs.el. We can't use `cl-deftype-satisfies' directly as the
> ;; relation type <-> predicate is not bijective (bug#45576).
> @@ -2102,10 +2110,10 @@ TARGET-BB-SYM is the symbol name of the target block."
> (when-let ((match
> (pcase insn
> (`(set ,lhs (,(pred comp--call-op-p) ,f . ,args))
> - (when-let ((cstr-f (gethash f comp-known-func-cstr-h)))
> + (when-let ((cstr-f (comp--get-function-cstr f)))
> (cl-values f cstr-f lhs args)))
> (`(,(pred comp--call-op-p) ,f . ,args)
> - (when-let ((cstr-f (gethash f comp-known-func-cstr-h)))
> + (when-let ((cstr-f (comp--get-function-cstr f)))
> (cl-values f cstr-f nil args))))))
> (cl-multiple-value-bind (f cstr-f lhs args) match
> (cl-loop
> @@ -2642,7 +2650,7 @@ Fold the call in case."
> (comp-cstr-imm-vld-p (car args)))
> (setf f (comp-cstr-imm (car args))
> args (cdr args)))
> - (when-let ((cstr-f (gethash f comp-known-func-cstr-h)))
> + (when-let ((cstr-f (comp--get-function-cstr f)))
> (let ((cstr (comp-cstr-f-ret cstr-f)))
> (when (comp-cstr-empty-p cstr)
> ;; Store it to be rewritten as non local exit.
> @@ -3301,11 +3309,13 @@ Prepare every function for final compilation and drive the C back-end."
> ;; are assumed just to be true. Use with extreme caution...
>
> (defun comp-hint-fixnum (x)
> - (declare (gv-setter (lambda (val) `(setf ,x ,val))))
> + (declare (type (function (t) fixnum))
> + (gv-setter (lambda (val) `(setf ,x ,val))))
> x)
>
> (defun comp-hint-cons (x)
> - (declare (gv-setter (lambda (val) `(setf ,x ,val))))
> + (declare (type (function (t) cons))
> + (gv-setter (lambda (val) `(setf ,x ,val))))
> x)
>
> \f
> diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el
> index 7e6db51b1d5..9edc11ad132 100644
> --- a/lisp/emacs-lisp/lisp.el
> +++ b/lisp/emacs-lisp/lisp.el
> @@ -534,7 +534,8 @@ major mode's decisions about context.")
> "Return the \"far end\" position of the buffer, in direction ARG.
> If ARG is positive, that's the end of the buffer.
> Otherwise, that's the beginning of the buffer."
> - (declare (side-effect-free error-free))
> + (declare (type (function ((or number marker)) integer))
> + (side-effect-free error-free))
> (if (> arg 0) (point-max) (point-min)))
>
> (defun end-of-defun (&optional arg interactive)
> diff --git a/lisp/emacs-lisp/regexp-opt.el b/lisp/emacs-lisp/regexp-opt.el
> index 59c1b7d8e10..f23343a34c6 100644
> --- a/lisp/emacs-lisp/regexp-opt.el
> +++ b/lisp/emacs-lisp/regexp-opt.el
> @@ -130,7 +130,8 @@ usually more efficient than that of a simplified version:
> (concat (car parens)
> (mapconcat \\='regexp-quote strings \"\\\\|\")
> (cdr parens))))"
> - (declare (pure t) (side-effect-free t))
> + (declare (type (function (list &optional t) string))
> + (pure t) (side-effect-free t))
> (save-match-data
> ;; Recurse on the sorted list.
> (let* ((max-lisp-eval-depth 10000)
> diff --git a/lisp/env.el b/lisp/env.el
> index e0a8df8476c..7d0c7dd0126 100644
> --- a/lisp/env.el
> +++ b/lisp/env.el
> @@ -207,7 +207,8 @@ parameter.
> Otherwise, this function searches `process-environment' for
> VARIABLE. If it is not found there, then it continues the search
> in the environment list of the selected frame."
> - (declare (side-effect-free t))
> + (declare (type (function (string &optional frame) (or null string)))
> + (side-effect-free t))
> (interactive (list (read-envvar-name "Get environment variable: " t)))
> (let ((value (getenv-internal (if (multibyte-string-p variable)
> (encode-coding-string
> diff --git a/lisp/files.el b/lisp/files.el
> index b7ebb727c72..c24e48e3db2 100644
> --- a/lisp/files.el
> +++ b/lisp/files.el
> @@ -862,6 +862,7 @@ GNU and Unix systems). Substitute environment variables into the
> resulting list of directory names. For an empty path element (i.e.,
> a leading or trailing separator, or two adjacent separators), return
> nil (meaning `default-directory') as the associated list element."
> + (declare (type (function (string) list)))
> (when (stringp search-path)
> (let ((spath (substitute-env-vars search-path))
> (double-slash-special-p
> diff --git a/lisp/help-fns.el b/lisp/help-fns.el
> index 9bf2f61aee6..182b22549b5 100644
> --- a/lisp/help-fns.el
> +++ b/lisp/help-fns.el
> @@ -732,7 +732,7 @@ the C sources, too."
> (insert (format
> (if (eq kind 'inferred)
> "\nInferred type: %s\n"
> - "\nType: %s\n")
> + "\nDeclared type: %s\n")
> type-spec))))
> (fill-region fill-begin (point))
> high-doc)))))
> diff --git a/lisp/simple.el b/lisp/simple.el
> index be64f3574e0..a459f6ecfd2 100644
> --- a/lisp/simple.el
> +++ b/lisp/simple.el
> @@ -1762,7 +1762,9 @@ not at the start of a line.
>
> When IGNORE-INVISIBLE-LINES is non-nil, invisible lines are not
> included in the count."
> - (declare (side-effect-free t))
> + (declare (type (function ((or integer marker) (or integer marker) &optional t)
> + integer))
> + (side-effect-free t))
> (save-excursion
> (save-restriction
> (narrow-to-region start end)
> @@ -6882,7 +6884,8 @@ is active, and returns an integer or nil in the usual way.
>
> If you are using this in an editing command, you are most likely making
> a mistake; see the documentation of `set-mark'."
> - (declare (side-effect-free t))
> + (declare (type (function (&optional t) (or integer null)))
> + (side-effect-free t))
> (if (or force (not transient-mark-mode) mark-active mark-even-if-inactive)
> (marker-position (mark-marker))
> (signal 'mark-inactive nil)))
> @@ -11163,7 +11166,8 @@ killed."
>
> (defun lax-plist-get (plist prop)
> "Extract a value from a property list, comparing with `equal'."
> - (declare (pure t) (side-effect-free t) (obsolete plist-get "29.1"))
> + (declare (type (function (list t) t))
> + (pure t) (side-effect-free t) (obsolete plist-get "29.1"))
> (plist-get plist prop #'equal))
>
> (defun lax-plist-put (plist prop val)
> diff --git a/lisp/subr.el b/lisp/subr.el
> index 352ecc315ef..92d1e50ab2c 100644
> --- a/lisp/subr.el
> +++ b/lisp/subr.el
> @@ -451,7 +451,8 @@ This function accepts any number of arguments in ARGUMENTS.
> Also see `always'."
> ;; Not declared `side-effect-free' because we don't want calls to it
> ;; elided; see `byte-compile-ignore'.
> - (declare (pure t) (completion ignore))
> + (declare (type (function (&rest t) null))
> + (pure t) (completion ignore))
> (interactive)
> nil)
>
> @@ -480,7 +481,8 @@ for the sake of consistency.
>
> To alter the look of the displayed error messages, you can use
> the `command-error-function' variable."
> - (declare (advertised-calling-convention (string &rest args) "23.1"))
> + (declare (type (function (string &rest t) nil))
> + (advertised-calling-convention (string &rest args) "23.1"))
> (signal 'error (list (apply #'format-message args))))
>
> (defun user-error (format &rest args)
> @@ -545,19 +547,22 @@ was called."
> "Return t if NUMBER is zero."
> ;; Used to be in C, but it's pointless since (= 0 n) is faster anyway because
> ;; = has a byte-code.
> - (declare (pure t) (side-effect-free t)
> + (declare (type (function (number) boolean))
> + (pure t) (side-effect-free t)
> (compiler-macro (lambda (_) `(= 0 ,number))))
> (= 0 number))
>
> (defun fixnump (object)
> "Return t if OBJECT is a fixnum."
> - (declare (side-effect-free error-free))
> + (declare (type (function (t) boolean))
> + (side-effect-free error-free))
> (and (integerp object)
> (<= most-negative-fixnum object most-positive-fixnum)))
>
> (defun bignump (object)
> "Return t if OBJECT is a bignum."
> - (declare (side-effect-free error-free))
> + (declare (type (function (t) boolean))
> + (side-effect-free error-free))
> (and (integerp object) (not (fixnump object))))
>
> (defun lsh (value count)
> @@ -570,7 +575,8 @@ Most uses of this function turn out to be mistakes. We recommend
> to use `ash' instead, unless COUNT could ever be negative, and
> if, when COUNT is negative, your program really needs the special
> treatment of negative COUNT provided by this function."
> - (declare (compiler-macro
> + (declare (type (function (integer integer) integer))
> + (compiler-macro
> (lambda (form)
> (macroexp-warn-and-return
> (format-message "avoid `lsh'; use `ash' instead")
> @@ -748,7 +754,8 @@ treatment of negative COUNT provided by this function."
> If LIST is nil, return nil.
> If N is non-nil, return the Nth-to-last link of LIST.
> If N is bigger than the length of LIST, return LIST."
> - (declare (pure t) (side-effect-free t)) ; pure up to mutation
> + (declare (type (function (list &optional integer) list))
> + (pure t) (side-effect-free t)) ; pure up to mutation
> (if n
> (and (>= n 0)
> (let ((m (safe-length list)))
> @@ -1585,7 +1592,8 @@ See also `current-global-map'.")
>
> (defun eventp (object)
> "Return non-nil if OBJECT is an input event or event object."
> - (declare (pure t) (side-effect-free error-free))
> + (declare (type (function (t) boolean))
> + (pure t) (side-effect-free error-free))
> (or (integerp object)
> (and (if (consp object)
> (setq object (car object))
> @@ -1652,7 +1660,8 @@ in the current Emacs session, then this function may return nil."
>
> (defsubst mouse-movement-p (object)
> "Return non-nil if OBJECT is a mouse movement event."
> - (declare (side-effect-free error-free))
> + (declare (type (function (t) boolean))
> + (side-effect-free error-free))
> (eq (car-safe object) 'mouse-movement))
>
> (defun mouse-event-p (object)
> @@ -1961,7 +1970,8 @@ be a list of the form returned by `event-start' and `event-end'."
>
> (defun log10 (x)
> "Return (log X 10), the log base 10 of X."
> - (declare (side-effect-free t) (obsolete log "24.4"))
> + (declare (type (function (number) float))
> + (side-effect-free t) (obsolete log "24.4"))
> (log x 10))
>
> (set-advertised-calling-convention
> @@ -3245,7 +3255,8 @@ It can be retrieved with `(process-get PROCESS PROPNAME)'."
>
> (defun memory-limit ()
> "Return an estimate of Emacs virtual memory usage, divided by 1024."
> - (declare (side-effect-free error-free))
> + (declare (type (function () integer))
> + (side-effect-free error-free))
> (let ((default-directory temporary-file-directory))
> (or (cdr (assq 'vsize (process-attributes (emacs-pid)))) 0)))
>
> @@ -6467,7 +6478,8 @@ To test whether a function can be called interactively, use
> `commandp'."
> ;; Kept around for now. See discussion at:
> ;; https://lists.gnu.org/r/emacs-devel/2020-08/msg00564.html
> - (declare (obsolete called-interactively-p "23.2")
> + (declare (type (function () boolean))
> + (obsolete called-interactively-p "23.2")
> (side-effect-free error-free))
> (called-interactively-p 'interactive))
>
> diff --git a/lisp/window.el b/lisp/window.el
> index cdc6f690bab..639090752be 100644
> --- a/lisp/window.el
> +++ b/lisp/window.el
> @@ -2515,7 +2515,8 @@ have special meanings:
>
> Any other value of ALL-FRAMES means consider all windows on the
> selected frame and no others."
> - (declare (side-effect-free error-free))
> + (declare (type (function (&optional t t t) (or window null)))
> + (side-effect-free error-free))
> (let ((windows (window-list-1 nil 'nomini all-frames))
> best-window best-time second-best-window second-best-time time)
> (dolist (window windows)
> @@ -2594,7 +2595,8 @@ have special meanings:
>
> Any other value of ALL-FRAMES means consider all windows on the
> selected frame and no others."
> - (declare (side-effect-free error-free))
> + (declare (type (function (&optional t t t) (or window null)))
> + (side-effect-free error-free))
> (let ((best-size 0)
> best-window size)
> (dolist (window (window-list-1 nil 'nomini all-frames))
> @@ -4089,7 +4091,8 @@ with a special meaning are:
>
> Anything else means consider all windows on the selected frame
> and no others."
> - (declare (side-effect-free error-free))
> + (declare (type (function (&optional t t) boolean))
> + (side-effect-free error-free))
> (let ((base-window (selected-window)))
> (if (and nomini (eq base-window (minibuffer-window)))
> (setq base-window (next-window base-window)))
^ permalink raw reply [flat|nested] 3+ messages in thread