GNU bug report logs - #74660
31.0.50; bind-keys has unexpected behavior when evaluated with eval-defun

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: emacs; Reported by: Dale <dale@HIDDEN>; dated Tue, 3 Dec 2024 00:51:02 UTC; Maintainer for emacs is bug-gnu-emacs@HIDDEN.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 3 Dec 2024 00:51:01 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Dec 02 19:51:01 2024
Received: from localhost ([127.0.0.1]:57113 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1tIH81-0002F3-4S
	for submit <at> debbugs.gnu.org; Mon, 02 Dec 2024 19:51:01 -0500
Received: from lists.gnu.org ([209.51.188.17]:35126)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <dale@HIDDEN>) id 1tIH7z-0002Et-Ah
 for submit <at> debbugs.gnu.org; Mon, 02 Dec 2024 19:50:59 -0500
Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <dale@HIDDEN>) id 1tIH7y-0000Di-NI
 for bug-gnu-emacs@HIDDEN; Mon, 02 Dec 2024 19:50:59 -0500
Received: from mail-yb1-xb35.google.com ([2607:f8b0:4864:20::b35])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <dale@HIDDEN>) id 1tIH7v-0004Bt-Au
 for bug-gnu-emacs@HIDDEN; Mon, 02 Dec 2024 19:50:58 -0500
Received: by mail-yb1-xb35.google.com with SMTP id
 3f1490d57ef6-e3824e1adcdso4059278276.3
 for <bug-gnu-emacs@HIDDEN>; Mon, 02 Dec 2024 16:50:54 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=codefu-org.20230601.gappssmtp.com; s=20230601; t=1733187052; x=1733791852;
 darn=gnu.org; 
 h=to:date:message-id:subject:mime-version:content-transfer-encoding
 :from:from:to:cc:subject:date:message-id:reply-to;
 bh=Grv5/WfLZWkyRyHwvGukTvn+Z9PtU1DuVd2aE8XGL/M=;
 b=wXuMDSxSLL+qfgu16F/wVFJIaV4FClDt5luVf2Dv6bwNb8sgOb7a9E0nS926jXOe8g
 sDo/pmjKC3/dYxmmpQLV5SKAOcrZRuuIQYYRknlbibk1OrUpKhuqPN1YBJYBPcQKxTBS
 WM5i979r8tc3/0kbX7F7Sj1WEFQuPpevUvFc8umeN9f1kP8XHwJJpITxVMGNbIoeDAZ1
 W1ARMFLS4J8/VijVxELFTvwX6IYX33//J6MGNIJWQViKYQ6SRtrJnFPDzLf3Twmb17Ex
 DiOSUojlvvF3IzJ1LG2rRYDBbHMMC8VHjSk30f3OeQcXTF0LQiEQu964angjrgyKYmWX
 65hw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1733187052; x=1733791852;
 h=to:date:message-id:subject:mime-version:content-transfer-encoding
 :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
 bh=Grv5/WfLZWkyRyHwvGukTvn+Z9PtU1DuVd2aE8XGL/M=;
 b=nsi0Y/CC9vwm0lsS83y5WpdGfvhE1DXHKkRDdqKCpH5/lN72ReZwKRwe7goHqP0t3N
 Gt71dF9Y3JeMj60ybEs9aFOhikOfPXKKQsdHhVuNXDzErF7hf3QPXw+TOIUE4S4EqQOL
 7RqOZ0P0QZGJHpTJb/QTsSUmBbhBLvf/J9+4v402OYrFOGyjV/PnlB+X3Id88hpnWvrB
 JaX1+oTrQ+giiN+Z9FCl+U1rQn2RZLnCA6M60BfGMeD3uecSHe1sis9QYx4XAvpS6Zl8
 5OlFWmpkMF+KSnVprhNau/J03ouqa6ILbJ10CPacy3czKRnEtYW8RDYv4aFMWz1wO8Vp
 Kdpw==
X-Gm-Message-State: AOJu0YxlVYc5ba7AmVWjeJ+5U6oXdaxtO/iGZfMnDzOIJpmJJVvH6HYi
 vlGwbHhs7D4aLsXJ4JD8sezO9E4kn/ltxGl4X0qclemrP4C6lk4kwUMKfXn4IEoAY1226wuwail
 vow==
X-Gm-Gg: ASbGnctWLxQJCvurjUe4d9sXJELepWAfF51zqMtqeMeb/jebnYjWDWcjDcw7BW9Dwgi
 JKTgcl2Ky4yJN8lXEd256rv6Hr2AvxFan4Ql8RaFHglRNXRmCvKz+6fBDIeuUY9J6+oKTi4lna2
 v/HQMVjv3tDF9KK8BZ2qsfghIZiz9EAv/QR8zI8vWg5smHsPHm0fn/VtHgK5foBWw1wCaPH5dEW
 btNdvAx5L5nOyGg/HUs6s1YO/Mv7YHETq2FMDHM/ex/z0+sHxGY0lRhai8jmwX5BvJ8gL2A
X-Google-Smtp-Source: AGHT+IE8l60NrMEVkL1sWI2q1I3XTMXVFBuXFPRm/SNaIgGGrAbhC5LDrTP/rWbZOO/5jlzRufl7yQ==
X-Received: by 2002:a05:6902:2b85:b0:e38:9bce:241e with SMTP id
 3f1490d57ef6-e39d39e66b9mr638719276.10.1733187052386; 
 Mon, 02 Dec 2024 16:50:52 -0800 (PST)
Received: from smtpclient.apple ([2604:5500:3160:3900:25ef:d3d1:7e3d:8577])
 by smtp.gmail.com with ESMTPSA id
 3f1490d57ef6-e3976c8ee16sm2761527276.58.2024.12.02.16.50.50
 for <bug-gnu-emacs@HIDDEN>
 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);
 Mon, 02 Dec 2024 16:50:51 -0800 (PST)
From: Dale <dale@HIDDEN>
Content-Type: text/plain;
	charset=us-ascii
Content-Transfer-Encoding: quoted-printable
Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3776.700.51.11.1\))
Subject: 31.0.50; bind-keys has unexpected behavior when evaluated with
 eval-defun
Message-Id: <AA641A01-49BB-4AD3-9318-2D6F0262B0FC@HIDDEN>
Date: Mon, 2 Dec 2024 18:50:38 -0600
To: bug-gnu-emacs@HIDDEN
X-Mailer: Apple Mail (2.3776.700.51.11.1)
Received-SPF: none client-ip=2607:f8b0:4864:20::b35;
 envelope-from=dale@HIDDEN; helo=mail-yb1-xb35.google.com
X-Spam_score_int: -18
X-Spam_score: -1.9
X-Spam_bar: -
X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,
 DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,
 SPF_NONE=0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

Start any Emacs that includes bind-key.el with "emacs -Q".  Then put the
following into an `emacs-lisp-mode' buffer (or anywhere C-M-x is bound
to `eval-defun'):

    (bind-keys :repeat-map foo-map
               ("n" . next-line)
               :exit
               ("q" . ignore))

Put the point anywhere in this form and press C-M-x (`eval-defun') =
twice.
Now look at the value of `foo-map'.

Expected value: (keymap (113 . ignore) (110 . next-line))
Both bindings are set.

Observed value: (keymap (113 . ignore))
Only the last binding is set.

I believe the problem is that `eval-defun' and friends treat `defvar`
specially via `elisp--eval-defun-1': normally `defvar' won't change the
value of SYMBOL if it is already bound, but `eval-defun' (and
`eval-last-sexp' and probably others) call `elisp--eval-defun-1' to
rewrite the `defvar' into a form that always sets ("re-initializes")
SYMBOL.

Additionally, `elisp--eval-defun-1' will recurse into `progn' forms to
apply this rewriting of `defvar'.

If you macroexpand the `bind-keys' form from my test case, you'll see
that `bind-keys' produces two `defvar' forms for the provided keymap:

    (progn
      (defvar foo-map (make-sparse-keymap))
      (put (function next-line) 'repeat-map 'foo-map)
      (bind-key "n" (function next-line) foo-map nil)
      (defvar foo-map (make-sparse-keymap))
      (bind-key "q" (function ignore) foo-map nil))

Normally this second `defvar' has no effect, but when you `eval-defun'
this `bind-keys' form, the special behavior from `elisp--eval-defun-1'
kicks in for `defvar', and so the second `defvar' clobbers the keymap
value that was set up by the first `defvar'.  (Actually, the first
`defvar' will also clobber the keymap, which may not be what the user
expects.)

You do have to `eval-defun' twice because `elisp--eval-defun-1' only
applies its special behavior when the variable being defined is unbound.
The first time through, `foo-map' is undefined, so `defvar' is left
alone, and the resulting value of `foo-map' is as expected.  The second
time through, `foo-map' is now bound, so the special behavior kicks in,
and both `defvar' forms set `foo-map' to an empty sparse keymap.

Normally I wouldn't open a bug for this, because this special behavior
for `eval-defun' is documented behavior.  However, I think the case of
`bind-keys' is problematic for two reasons:

1. It is not immediately obvious that the `bind-keys' macro is using
   `defvar'.

2. `bind-keys' is something users put in their init file, and so they're
   likely going to be using C-M-x or C-x C-e a lot while they're
   tweaking and testing their init file (exactly what happened to me).

Further notes:

I do find the special treatment of `defvar' (and `defcustom') with C-M-x
and C-x C-e useful, so I'm not proposing removing that. :)

Arguably, `elisp--eval-defun-1' should notice when there are more than
one `defvar' forms for the same variable, and only the first should
exhibit the special "always initialize SYMBOL" behavior.  I don't want
to make that argument, though, because I feel the special-casing of
`defvar' is surprising enough as-is.  I don't want to make that more
complex.

Maybe `bind-keys' shouldn't emit more than one `defvar' form for a
keymap?  Or maybe it shouldn't emit any `defvar' forms if it finds the
keymap is already bound?

Thank you for maintaining Emacs :)


In GNU Emacs 31.0.50 (build 1, aarch64-apple-darwin23.6.0, NS
appkit-2487.70 Version 14.7 (Build 23H124)) of 2024-10-12 built on
daleRepository revision: 05e418e0688f24b5518e38e54bde96a639f7c70d
Repository branch: master
Windowing system distributor 'Apple', version 10.3.2487
System Description:  macOS 14.7.1

Configured using:
 'configure --without-x --with-xwidgets --with-json --with-tree-sitter =
--without-imagemagick --with-xpm --with-jpeg --with-tiff --with-gif =
--with-png --with-rsvg --with-webp --with-sqlite3 --with-lcms2 =
--with-cairo --with-xml2 --with-gnutls --with-zlib --with-modules =
--with-threads --with-native-compilation --with-ns =
--enable-ns-self-contained 'CFLAGS=3D -D_DARWIN_UNLIMITED_SELECT=3D1 =
-DFD_SETSIZE=3D10240''





Acknowledgement sent to Dale <dale@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to bug-gnu-emacs@HIDDEN:
bug#74660; Package emacs. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Sun, 12 Jan 2025 05:45:02 UTC

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