* lisp/emacs-lisp/cl-macs.el (cl-flet, cl-labels): Wrap function
bodies in `cl-block`.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--test-flet-block): New test.
Allow `cl-labels` to use the same (FUNC EXP) bindings as were already added
to `cl-flet` in Emacs-25. The Info doc (mistakenly) already documented this
new feature.
* lisp/emacs-lisp/cl-macs.el (cl--self-tco-on-form): New function.
(cl-labels): Use it to add support for (FUNC EXP) bindings.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels): Add test for
tail-recursive (FUNC EXP) bindings.
* lisp/emacs-lisp/cl-macs.el (cl-flet): Fix debug spec.
(cl-defun): Allow only symbols as function names in debug spec.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-flet/edebug): New test
case.
* lisp/emacs-lisp/bytecomp.el (byte-compile-form): Turn "cannot use
lexical var" errors into warnings.
Make the obey `with-suppressed-warnings`.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-&key-arguments):
Suppress warnings.
* lisp/emacs-lisp/cl-macs.el (cl--slet): New function, partly extracted
from `cl--slet*`.
(cl--slet*): Use it.
(cl--defsubst-expand): Use it to fix bug#47552.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-defstruct-dynbound-label):
New test.
* lisp/emacs-lisp/cl-macs.el (cl--slet*): New function.
(cl--transform-lambda): Use it to fix bug#47552.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-&key-arguments): Add test.
* test/lisp/emacs-lisp/cl-macs-tests.el
(cl-macs-test--symbol-macrolet):
* test/lisp/emacs-lisp/cl-print-tests.el
(cl-print-tests-ellipsis-circular):
* test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
(eieio-test-persist-interior-lists):
* test/lisp/textmodes/reftex-tests.el (reftex-all-used-citation-keys):
* test/src/xdisp-tests.el (xdisp-tests--minibuffer-resizing):
* test/src/fns-tests.el (test-vector-delete):
Mutate created objects, not constants.
* test/lisp/emacs-lisp/subr-x-tests.el
(subr-x-test-add-display-text-property): Mutate a created string, and
compare using `equal-including-properties` without which the test was
rather meaningless.
* test/lisp/net/tramp-archive-tests.el
(tramp-archive-test16-directory-files): Don't mutate.
* lisp/emacs-lisp/cl-macs.el (cl-case): Check that the case is of the
form (quote FOO), not just (quote).
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-case-no-warning): New unit test.
* lisp/emacs-lisp/cl-macs.el (cl-case): Warn if the user passes a nil
key list (which would never match). Warn about quoted symbols that
should probably be unquoted.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-case-warning): New unit
test (bug#51368).
* lisp/emacs-lisp/cl-macs.el (cl-case): Warn if the user passes a nil
key list (which would never match). Warn about quoted symbols that
should probably be unquoted.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-case-warning): New unit
test (bug#51368).
The recent fix for bug#57397 introduced a regression, breaking
the `cl-lib-symbol-macrolet-hide` test. It turned out that the
origin of the problem was that `gv.el` uses `macroexpand-1` which
does not (can't) use `macroexpand` but `cl-symbol-macrolet` failed
to advise `macroexpand-1` the way it advised `macroexpand`.
To fix this, we change `cl-symbol-macrolet` so it advises both, and we
do that with a new `macroexpand` advice which delegates the bulk of
the work to `macroexpand-1`.
Along the way, I bumped into another bug in the interaction between
`cl-letf` and `cl-symbol-macrolet`, which I tried to fix in `cl-letf`.
I hear the war on `cl-symbol-macrolet` was a failure.
Maybe ... just say no?
* lisp/emacs-lisp/cl-macs.el (cl--sm-macroexpand-1): New function,
extracted from `cl--sm-macroexpand`.
(cl--sm-macroexpand): Rewrite completely.
(cl-symbol-macrolet): Advise both `macroexpand` and `macroexpand-1`.
(cl--letf): Don't use the "simple variable" code for symbol macros.
* test/lisp/emacs-lisp/cl-lib-tests.el (cl-lib-symbol-macrolet-hide):
Revert last change because the test was right.
* test/lisp/emacs-lisp/cl-macs-tests.el
(cl-macs-test--symbol-macrolet): Add a test case.
* lisp/emacs-lisp/gv.el (gv-get): Obey symbol macros.
* lisp/emacs-lisp/cl-macs.el (cl--letf): Remove workaround placed to
try and handle symbol macros.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-test--symbol-macrolet):
Add new testcase.
For example, 'xref-item' uses the list form of ':noinline'.
* lisp/emacs-lisp/cl-macs.el (cl-defstruct): Accept ':noinline' and
':named' with an argument.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-defstruct/edebug): New
unit test.
* lisp/emacs-lisp/cl-macs.el (cl-define-compiler-macro-list): New
Edebug element specification.
(cl-define-compiler-macro): Use it.
* test/lisp/emacs-lisp/cl-macs-tests.el
(cl-define-compiler-macro/edebug): New unit test.
This fixes a known bug in `named-let`.
* lisp/emacs-lisp/cl-macs.el (cl--self-tco): Prevent TCO from inside
dynamic variable bindings.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels): Add test.
Allow a condition-case handler on the form (:success BODY) to be
specified as the success continuation of the protected form, with
the specified variable bound to its result.
* src/eval.c (Fcondition_case): Update the doc string.
(internal_lisp_condition_case): Implement in interpreter.
(syms_of_eval): Defsym :success.
* lisp/emacs-lisp/bytecomp.el (byte-compile-condition-case):
Implement in byte-compiler.
* lisp/emacs-lisp/cl-macs.el (cl--self-tco): Allow self-TCO
from success handler.
* doc/lispref/control.texi (Handling Errors): Update manual.
* etc/NEWS: Announce.
* test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases)
(bytecomp-condition-case-success):
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels):
Add test cases.
* lisp/emacs-lisp/cl-macs.el (cl--self-tco): Recognise
`condition-case` handlers as being in the tail position.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels):
Extend test.
Implement a limited form of tail-call optimization for the special
case of recursive functions defined with `cl-labels`. Only self-recursion
is optimized, no attempt is made to handle more complex cases such a mutual
recursion.
The main benefit is to reduce the use of the stack, tho in my limited
tests, this can also improve performance (about half of the way to
a hand-written `while` loop).
(cl--self-tco): New function.
(cl-labels): Use it.
* lisp/subr.el (letrec): Optimize single-binding corner case.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels): Add tests
to check that TCO is working.
* lisp/emacs-lisp/cl-macs.el (cl--parse-loop-clause): Put the temp-idx
increment in cl--loop-body, leaving just the side-effect free testing
of the index for both cl--loop-body and cl--loop-conditions.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-loop-and-arrays):
Extend test to cover this case.
It fails when using 'and' (parallel bindings) for arrays (Bug#40727).
* lisp/emacs-lisp/cl-macs.el (cl--parse-loop-clause): Revert to
recomputing array length.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-loop-and-arrays): New
test.
* lisp/emacs-lisp/cl-preloaded.el (cl-struct-define): Don't allow
structures with the same names as builtin types.
(cl--typeof-types, cl--all-builtin-types): Move from cl-generic.el and
rename.
(cl--struct-name-p): New helper function.
* lisp/emacs-lisp/cl-macs.el (cl-defstruct): Don't allow structures
with the same names as builtin types.
* lisp/emacs-lisp/cl-generic.el (cl--generic-typeof-generalizer)
(cl-generic-generalizers): Adapt to name change.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-defstruct/builtin-type):
* test/lisp/emacs-lisp/cl-preloaded-tests.el
(cl-struct-define/builtin-type): New unit tests.
* etc/NEWS: Document changed behavior.
Consider the expansion of `cl-loop' with a `for' clause and more
than one internal variables, X, Y, processed in parallel.
Each step updates X and Y right after update the loop variable, K; if
either X or Y depend on K, then some forms of the body are
evaluated with the wrong K (Bug#29799).
For instance, consider the following code:
(cl-loop for k below 2
for x = (progn (message "k = %d" k) 1)
and y = 1)
This code should show in *Messages*:
k = 0
k = 1
Instead, the code shows:
k = 0
k = 1
k = 2
To prevent this we must ensure that the loop condition is still
satisfied right after update the loop variable.
In the macro expansion of the example above, right after:
(setq k (+ k 1))
evaluate the rest of the body forms iif the condition
(< k 2)
is still valid.
* lisp/emacs-lisp/cl-macs.el (cl--loop-guard-cond): New variable.
(cl--parse-loop-clause): Set it non-nil if the loop contains
a for/as clause.
(cl-loop): After update the loop variable, evaluate the remaining of
the body forms just if the loop condition is still valid (Bug#29799).
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-loop-for-as-equals-and):
New test.