GNU bug report logs - #65344
28.2; Unable to Edebug cl-flet form which uses argument destructuring

Previous Next

Package: emacs;

Reported by: Brandon Irizarry <brandon.irizarry <at> gmail.com>

Date: Wed, 16 Aug 2023 18:23:02 UTC

Severity: normal

Found in version 28.2

Fixed in version 30.1

Done: Gerd Möllmann <gerd.moellmann <at> gmail.com>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Gerd Möllmann <gerd.moellmann <at> gmail.com>
Cc: Michael Heerdegen <michael_heerdegen <at> web.de>, brandon.irizarry <at> gmail.com, Mattias Engdegård <mattias.engdegard <at> gmail.com>, Michael Albinus <michael.albinus <at> gmx.de>, 65344 <at> debbugs.gnu.org
Subject: bug#65344: 28.2; Unable to Edebug cl-flet form which uses argument destructuring
Date: Sat, 02 Sep 2023 15:27:51 -0400
>> In this case, the code for F will be run in the body of the
>> flet. Doesn't that qualify as being run later, as you describe above, 
>> ignoring the "non-instrumented" part, maybe?
>
> No, in the above case the `def-form` is
>
>     (lambda () (list 1 2))
>
> which will be "run" right when we enter the `cl-flet` ("run" is an
> exaggeration here since this lambda is a constant so it'll just
> self-evaluate) and not when `f` is called.

More specifically, the annotated code of

    (defun sm-foo (x)
      (cl-flet ((f (prog1 (lambda (y) (+ x y)) 0)))
        (f 5)))

stored into (symbol-function 'sm-foo) now looks like:

    (closure (t) (x)
     (edebug-enter 'sm-foo (list x)
      #'(lambda nil :closure-dont-trim-context
          (edebug-after (edebug-before 0) 3
           (let* ((--cl-f--
                   (edebug-enter 'f <at> cl-flet <at> 4 nil
                    #'(lambda nil :closure-dont-trim-context
                        (edebug-after (edebug-before 0) 1
                         (prog1
                             #'(lambda (y)
                                (edebug-enter 'edebug-anon5 (list y)
                                 #'(lambda nil :closure-dont-trim-context
                                    (edebug-after (edebug-before 0) 3
                                     (+ (edebug-after 0 1 x)
                                      (edebug-after 0 2 y))))))
                           0))))))
             (progn
               (edebug-after (edebug-before 1) 2
                (funcall --cl-f-- 5))))))))

As you can see for `sm-foo` itself, the

    (edebug-enter 'sm-foo (list x)
     #'(lambda nil :closure-dont-trim-context

is (correctly) placed at the very beginning of the body of the function,
so that code coverage can track whether `sm-foo` was called or not.

In contrast the

    (edebug-enter 'f <at> cl-flet <at> 4 nil
     #'(lambda nil :closure-dont-trim-context

is placed around the code which will compute&return the `f <at> cl-flet <at> 4`
function, but not inside its body, which instead gets

    (edebug-enter 'edebug-anon5 (list y)
     #'(lambda nil :closure-dont-trim-context

It's actually difficult (and in general impossible) to associate the
name `f <at> cl-flet <at> 4` with the corresponding `lambda`, so the use of
`edebug-anon5` is largely unavoidable here.  But making the code-coverage
say that `f <at> cl-flet <at> 4` is called just because we computed that function
(regardless if it's been called) is a problem.


        Stefan





This bug report was last modified 1 year and 261 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.