From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Gemini Lasswell Newsgroups: gmane.emacs.bugs Subject: bug#29919: 26.0.90; Incorrect Edebug spec for cl-macrolet Date: Tue, 24 Jul 2018 16:20:42 -0700 Message-ID: <87k1pkqkz9.fsf@runbox.com> References: <87vagmwpf2.fsf@runbox.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1532474411 3835 195.159.176.226 (24 Jul 2018 23:20:11 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 24 Jul 2018 23:20:11 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1.50 (gnu/linux) Cc: 29919@debbugs.gnu.org, Kaushal Modi To: Gemini Lasswell Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Jul 25 01:20:06 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fi6b7-0000pp-SD for geb-bug-gnu-emacs@m.gmane.org; Wed, 25 Jul 2018 01:20:06 +0200 Original-Received: from localhost ([::1]:43000 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fi6dD-0000x0-3C for geb-bug-gnu-emacs@m.gmane.org; Tue, 24 Jul 2018 19:22:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:45972) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fi6d5-0000wi-HW for bug-gnu-emacs@gnu.org; Tue, 24 Jul 2018 19:22:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fi6d0-0007xq-HW for bug-gnu-emacs@gnu.org; Tue, 24 Jul 2018 19:22:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:50849) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fi6d0-0007xM-2M for bug-gnu-emacs@gnu.org; Tue, 24 Jul 2018 19:22:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1fi6cz-0003Jc-QK for bug-gnu-emacs@gnu.org; Tue, 24 Jul 2018 19:22:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Gemini Lasswell Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 24 Jul 2018 23:22:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 29919 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 29919-submit@debbugs.gnu.org id=B29919.153247448012696 (code B ref 29919); Tue, 24 Jul 2018 23:22:01 +0000 Original-Received: (at 29919) by debbugs.gnu.org; 24 Jul 2018 23:21:20 +0000 Original-Received: from localhost ([127.0.0.1]:55867 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fi6cJ-0003Ii-NQ for submit@debbugs.gnu.org; Tue, 24 Jul 2018 19:21:20 -0400 Original-Received: from aibo.runbox.com ([91.220.196.211]:43592) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fi6cH-0003IY-3w for 29919@debbugs.gnu.org; Tue, 24 Jul 2018 19:21:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=runbox.com; s=rbselector1; h=Content-Type:MIME-Version:Message-ID:In-Reply-To:Date: References:Subject:Cc:To:From; bh=7yYg0qb0roAvxM8i/Ej3PcJO0WDTYR5bM4sZ1h0AZzw=; b=SUUzKyLjxRsRTRkKQEcKrj1f7x BSLg2r40PN0jwx6m+/gRo6gBg0tQ1VlWd0D3CH9Va7v/AgX9pyn4dMgnELdxGDLMNsXotPgWn8+tq JSeqsyYXeFnUdBuX5ygwSehwoBcYOR9nVIXPd0sntPf9HwJJoALEXLcRpD0957eUHEGhvArjTFXth /L0Y+hOe/eKX5ksvtMwl7l+DdZGJyzf941QQYZ4ux6x414oPMIbxC6nOxrBVyxUvsqG7niJPtG1zi LI/KpcFzHTBZ6vwkbpNwyPue7l1V0O2sf0R/HpdhDMbEEH+ZQTlcyyiWQhX022B/oyAScTDizIP1u t4CfdI1g==; Original-Received: from [10.9.9.212] (helo=mailfront12.runbox.com) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1fi6cF-0001RK-Op; Wed, 25 Jul 2018 01:21:15 +0200 Original-Received: by mailfront12.runbox.com with esmtpsa (uid:179284 ) (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) id 1fi6bl-0000rM-Lu; Wed, 25 Jul 2018 01:20:47 +0200 In-Reply-To: <87vagmwpf2.fsf@runbox.com> (Gemini Lasswell's message of "Sun, 31 Dec 2017 13:36:17 -0800") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:148905 Archived-At: --=-=-= Content-Type: text/plain Gemini Lasswell writes: > Edebug gives an error when trying to instrument a function which uses > cl-macrolet to define a macro with an argument list containing &rest. > > Looks to me like the problem is that the Edebug spec is using (&rest arg) > when it should be using cl-macro-list, assuming that cl-macrolet > supports full CL argument lists. That was one of the problems, and the other problem was that Edebug would wrap all the arguments to the temporary macros, even those that are not evaluated, causing breakage. I solved that in the attached patch by writing Edebug match functions for cl-macrolet which treat the temporary macros like normal macros without Edebug specs, which means none of their arguments get wrapped. This fixes the breakage but means you can't Edebug through those of the arguments which do get evaluated. To do that we'd have to add the ability to have (declare (debug ...)) forms in the temporary macro bodies so that they could have temporary Edebug specs, which would mean changing cl-macrolet itself instead of just its Edebug spec. Kaushal, I was able to step through org-export-data with this patch in place. Let me know if you are able to give it a try. --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=0001-Fix-Edebug-spec-for-cl-macrolet-bug-29919.patch >From 6a9c02ac9b1515d44d1c28c82ee4d19e231797a8 Mon Sep 17 00:00:00 2001 From: Gemini Lasswell Date: Tue, 24 Jul 2018 09:07:18 -0700 Subject: [PATCH] Fix Edebug spec for cl-macrolet (bug#29919) Add an Edebug matching function for cl-macrolet which collects the symbols used in the bindings. When those symbols are found in the body of the expression, they are treated as macros without Edebug specs. * lisp/emacs-lisp/edebug.el (edebug--cl-macrolet-defs): New variable. (edebug-list-form-args): Use it. (edebug--current-cl-macrolet-defs): New variable. (edebug-match-cl-macrolet-expr, edebug-match-cl-macrolet-name) (edebug-match-cl-macrolet-body): New functions. * lisp/emacs-lisp/cl-macs.el (cl-macrolet): Use cl-macrolet-expr for Edebug spec. * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-cl-macrolet): New test. * test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el (edebug-test-code-use-cl-macrolet): New function. --- lisp/emacs-lisp/cl-macs.el | 5 +-- lisp/emacs-lisp/edebug.el | 47 ++++++++++++++++++++++ .../edebug-resources/edebug-test-code.el | 7 ++++ test/lisp/emacs-lisp/edebug-tests.el | 11 +++++ 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 011965acb5..d0d1c3b156 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2083,10 +2083,7 @@ cl-macrolet \(fn ((NAME ARGLIST BODY...) ...) FORM...)" (declare (indent 1) - (debug - ((&rest (&define name (&rest arg) cl-declarations-or-string - def-body)) - cl-declarations body))) + (debug (cl-macrolet-expr))) (if (cdr bindings) `(cl-macrolet (,(car bindings)) (cl-macrolet ,(cdr bindings) ,@body)) (if (null bindings) (macroexp-progn body) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index e759c5b5b2..f0c0db182e 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1198,6 +1198,8 @@ edebug-def-interactive (defvar edebug-inside-func) ;; whether code is inside function context. ;; Currently def-form sets this to nil; def-body sets it to t. +(defvar edebug--cl-macrolet-defs) ;; Fully defined below. + (defun edebug-interactive-p-name () ;; Return a unique symbol for the variable used to store the ;; status of interactive-p for this function. @@ -1463,6 +1465,11 @@ edebug-list-form-args ;; Helper for edebug-list-form (let ((spec (get-edebug-spec head))) (cond + ;; Treat cl-macrolet bindings like macros with no spec. + ((member head edebug--cl-macrolet-defs) + (if edebug-eval-macro-args + (edebug-forms cursor) + (edebug-sexps cursor))) (spec (cond ((consp spec) @@ -1651,6 +1658,9 @@ edebug-match-specs ;; (function . edebug-match-function) (lambda-expr . edebug-match-lambda-expr) (cl-generic-method-args . edebug-match-cl-generic-method-args) + (cl-macrolet-expr . edebug-match-cl-macrolet-expr) + (cl-macrolet-name . edebug-match-cl-macrolet-name) + (cl-macrolet-body . edebug-match-cl-macrolet-body) (¬ . edebug-match-¬) (&key . edebug-match-&key) (place . edebug-match-place) @@ -1954,6 +1964,43 @@ edebug-match-cl-generic-method-args (edebug-move-cursor cursor) (list args))) +(defvar edebug--cl-macrolet-defs nil + "List of symbols found within the bindings of enclosing `cl-macrolet' forms.") +(defvar edebug--current-cl-macrolet-defs nil + "List of symbols found within the bindings of the current `cl-macrolet' form.") + +(defun edebug-match-cl-macrolet-expr (cursor) + "Match a `cl-macrolet' form at CURSOR." + (let (edebug--current-cl-macrolet-defs) + (edebug-match cursor + '((&rest (&define cl-macrolet-name cl-macro-list + cl-declarations-or-string + def-body)) + cl-declarations cl-macrolet-body)))) + +(defun edebug-match-cl-macrolet-name (cursor) + "Match the name in a `cl-macrolet' binding at CURSOR. +Collect the names in `edebug--cl-macrolet-defs' where they +will be checked by `edebug-list-form-args' and treated as +macros without a spec." + (let ((name (edebug-top-element-required cursor "Expected name"))) + (when (not (symbolp name)) + (edebug-no-match cursor "Bad name:" name)) + ;; Change edebug-def-name to avoid conflicts with + ;; names at global scope. + (setq edebug-def-name (gensym "edebug-anon")) + (edebug-move-cursor cursor) + (push name edebug--current-cl-macrolet-defs) + (list name))) + +(defun edebug-match-cl-macrolet-body (cursor) + "Match the body of a `cl-macrolet' expression at CURSOR. +Put the definitions collected in `edebug--current-cl-macrolet-defs' +into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." + (let ((edebug--cl-macrolet-defs (nconc edebug--current-cl-macrolet-defs + edebug--cl-macrolet-defs))) + (edebug-match-body cursor))) + (defun edebug-match-arg (cursor) ;; set the def-args bound in edebug-defining-form (let ((edebug-arg (edebug-top-element-required cursor "Expected arg"))) diff --git a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el index e86c2f1c1e..f3fc78d4e1 100644 --- a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el +++ b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el @@ -130,5 +130,12 @@ edebug-test-code-use-destructuring-bind (let ((two 2) (three 3)) (cl-destructuring-bind (x . y) (cons two three) (+ x!x! y!y!)))) +(defun edebug-test-code-use-cl-macrolet (x) + (cl-macrolet ((wrap (func &rest args) + `(format "The result of applying %s to %s is %S" + ',func!func! ',args + ,(cons func args)))) + (wrap + 1 x))) + (provide 'edebug-test-code) ;;; edebug-test-code.el ends here diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el index 85f6bd47db..7d780edf28 100644 --- a/test/lisp/emacs-lisp/edebug-tests.el +++ b/test/lisp/emacs-lisp/edebug-tests.el @@ -913,5 +913,16 @@ edebug-tests-setup-code-file "g" (should (equal edebug-tests-@-result 5))))) +(ert-deftest edebug-tests-cl-macrolet () + "Edebug can instrument `cl-macrolet' expressions. (Bug#29919)" + (edebug-tests-with-normal-env + (edebug-tests-setup-@ "use-cl-macrolet" '(10) t) + (edebug-tests-run-kbd-macro + "@ SPC SPC" + (edebug-tests-should-be-at "use-cl-macrolet" "func") + (edebug-tests-should-match-result-in-messages "+") + "g" + (should (equal edebug-tests-@-result "The result of applying + to (1 x) is 11"))))) + (provide 'edebug-tests) ;;; edebug-tests.el ends here -- 2.16.4 --=-=-=--