From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#65051: internal_equal manipulates symbols with position without checking symbols-with-pos-enabled. Date: Sat, 5 Aug 2023 10:45:37 +0000 Message-ID: References: <83leeqvpx8.fsf@gnu.org> <83h6pevnd0.fsf@gnu.org> <838raqvg91.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="17907"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 65051@debbugs.gnu.org, acm@muc.de To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Aug 05 12:46:24 2023 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qSEng-0004To-BO for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 05 Aug 2023 12:46:24 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qSEnM-0006fb-4v; Sat, 05 Aug 2023 06:46:04 -0400 Original-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 ) id 1qSEnK-0006f4-BD for bug-gnu-emacs@gnu.org; Sat, 05 Aug 2023 06:46:02 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qSEnJ-0002b1-U3 for bug-gnu-emacs@gnu.org; Sat, 05 Aug 2023 06:46:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qSEnJ-0004rh-PP for bug-gnu-emacs@gnu.org; Sat, 05 Aug 2023 06:46:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 05 Aug 2023 10:46:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 65051 X-GNU-PR-Package: emacs Original-Received: via spool by 65051-submit@debbugs.gnu.org id=B65051.169123234818682 (code B ref 65051); Sat, 05 Aug 2023 10:46:01 +0000 Original-Received: (at 65051) by debbugs.gnu.org; 5 Aug 2023 10:45:48 +0000 Original-Received: from localhost ([127.0.0.1]:55773 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qSEn5-0004rF-Bu for submit@debbugs.gnu.org; Sat, 05 Aug 2023 06:45:48 -0400 Original-Received: from mx3.muc.de ([193.149.48.5]:35070) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qSEn3-0004r0-AD for 65051@debbugs.gnu.org; Sat, 05 Aug 2023 06:45:46 -0400 Original-Received: (qmail 39781 invoked by uid 3782); 5 Aug 2023 12:45:38 +0200 Original-Received: from acm.muc.de (p4fe15973.dip0.t-ipconnect.de [79.225.89.115]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Sat, 05 Aug 2023 12:45:38 +0200 Original-Received: (qmail 3794 invoked by uid 1000); 5 Aug 2023 10:45:37 -0000 Content-Disposition: inline In-Reply-To: <838raqvg91.fsf@gnu.org> X-Submission-Agent: TMDA/1.3.x (Ph3nix) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list 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-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:266764 Archived-At: Hello, Eli. On Fri, Aug 04, 2023 at 21:01:30 +0300, Eli Zaretskii wrote: > > Date: Fri, 4 Aug 2023 17:06:10 +0000 > > Cc: 65051@debbugs.gnu.org > > From: Alan Mackenzie > > On Fri, Aug 04, 2023 at 18:27:55 +0300, Eli Zaretskii wrote: > > > > Date: Fri, 4 Aug 2023 14:59:58 +0000 > > > > Cc: 65051@debbugs.gnu.org, acm@muc.de > > > > From: Alan Mackenzie > > > > > What will happen to the comparison in internal_equal when > > > > > symbols_with_pos_enabled is zero and the two objects have different > > > > > positions, or one has a position, the other doesn't? > > > > In these cases, equal will return nil. This is correct. > > > It is? I thought when symbols with position are disabled, symbols > > > that are 'eq', but have different positions, should compare equal? > > > Why not? > > With symbols-with-pos-enabled nil, # is not EQ to > > #. Neither are these two objects `equal'. This is > > because the special, time consuming processing which makes them EQ or > > `equal' is enabled by that variable being bound to non-nil. > But I thought that with symbols-with-pos-enabled OFF, we just ignore > the positions? Truth is, neither the ELisp manual nor the doc string > tell us what happens when this variable is nil, they only tell what > happens when it's non-nil. So how about documenting that somewhere? OK, please see the patch below. > > That's the theory. In practice, the handling in internal_equal forgot to > > check for symbols-with-pos-enabled. That's what I want to fix, now. > I understand, but I question the correctness of your proposed fix. > And for now, I'm utterly confused regarding the expected semantics of > these comparisons when symbols-with-pos-enabled is nil. > > > > In the other case, when two symbols with position have the same base > > > > symbol and the same position, yet aren't identical, this will also return > > > > nil, which is incorrect. > > > How can they be not identical if the symbols and the positions are the > > > same? Or maybe I don't understand what you mean by "base symbol"? > > By "base symbol" I mean 'foo in #. By "identical" I > > meant that the two Lisp_Objects would have the same hex value (i.e. be > > EQ without symbols-with-pos-enabled), as contrasted to two distinct > > Lisp_Objects with the same base symbol, and the same position, i.e. > > should be `equal'. > So we can have two different copies of #, such that > their hex values are different? Isn't that a bug? why don't we > conflate such identical symbols? No, it's not a bug, anymore than having two `equal' copies of '(a b c) would be a bug. It's vanishingly unlikely to happen in practice. I think it could only happen if a user creates a SWP with something like (setq bar (position-symbol 'foo 42)) , when there is already such a SWP created by read-positioning-symbols. Or, perhaps, if reading one function produced a certain SWP which hangs around in a variable such as cl--labels-convert-cache, and reading the next function produces another SWP which happens to have the same bare symbol and position. Anyway, I've added code (in that patch below) to check two SWPs properly in the event of symbols-with-pos-enabled being nil. As already discussed, this is intended for master, not the release branch. diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi index 34db0caf3a8..a6ecfe896ad 100644 --- a/doc/lispref/symbols.texi +++ b/doc/lispref/symbols.texi @@ -784,9 +784,11 @@ Symbols with Position @cindex bare symbol A @dfn{symbol with position} is a symbol, the @dfn{bare symbol}, together with an unsigned integer called the @dfn{position}. These -objects are intended for use by the byte compiler, which records in +objects are for the use of the byte compiler, which records in them the position of each symbol occurrence and uses those positions -in warning and error messages. +in warning and error messages. They shouldn't normally be used +otherwise. Doing so can cause unexpected results with basic Emacs +functions such as @code{eq} and @code{equal}. The printed representation of a symbol with position uses the hash notation outlined in @ref{Printed Representation}. It looks like @@ -798,11 +800,20 @@ Symbols with Position For most purposes, when the flag variable @code{symbols-with-pos-enabled} is non-@code{nil}, symbols with -positions behave just as bare symbols do. For example, @samp{(eq -# foo)} has a value @code{t} when that variable -is set (but @code{nil} when it isn't set). Most of the time in Emacs this -variable is @code{nil}, but the byte compiler binds it to @code{t} -when it runs. +positions behave just as their bare symbols do. For example, +@samp{(eq # foo)} has a value @code{t} when the +variable is set; likewise, @code{equal} will treat a symbol with +position argument as its bare symbol. + +When @code{symbols-with-pos-enabled} is @code{nil}, any symbols with +position continue to exist, but do not behave as symbols, or have the +other useful properties outlined in the previous paragraph. @code{eq} +returns @code{t} when given identical arguments, and @code{equal} +returns @code{t} when given arguments with @code{equal} components. + +Most of the time in Emacs @code{symbols-with-pos-enabled} is +@code{nil}, but the byte compiler and the native compiler bind it to +@code{t} when they run. Typically, symbols with position are created by the byte compiler calling the reader function @code{read-positioning-symbols} @@ -820,7 +831,7 @@ Symbols with Position a symbol with position, ignoring the position. @end defvar -@defun symbol-with-pos-p symbol. +@defun symbol-with-pos-p symbol This function returns @code{t} if @var{symbol} is a symbol with position, @code{nil} otherwise. @end defun diff --git a/src/fns.c b/src/fns.c index bfd19e8c8f2..d47098c8791 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2773,10 +2773,13 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, /* A symbol with position compares the contained symbol, and is `equal' to the corresponding ordinary symbol. */ - if (SYMBOL_WITH_POS_P (o1)) - o1 = SYMBOL_WITH_POS_SYM (o1); - if (SYMBOL_WITH_POS_P (o2)) - o2 = SYMBOL_WITH_POS_SYM (o2); + if (symbols_with_pos_enabled) + { + if (SYMBOL_WITH_POS_P (o1)) + o1 = SYMBOL_WITH_POS_SYM (o1); + if (SYMBOL_WITH_POS_P (o2)) + o2 = SYMBOL_WITH_POS_SYM (o2); + } if (BASE_EQ (o1, o2)) return true; @@ -2824,8 +2827,8 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, if (ASIZE (o2) != size) return false; - /* Compare bignums, overlays, markers, and boolvectors - specially, by comparing their values. */ + /* Compare bignums, overlays, markers, boolvectors, and + symbols with position specially, by comparing their values. */ if (BIGNUMP (o1)) return mpz_cmp (*xbignum_val (o1), *xbignum_val (o2)) == 0; if (OVERLAYP (o1)) @@ -2857,6 +2860,13 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, if (TS_NODEP (o1)) return treesit_node_eq (o1, o2); #endif + if (SYMBOL_WITH_POS_P(o1)) /* symbols_with_pos_enabled is false. */ + return (internal_equal (XSYMBOL_WITH_POS (o1)->sym, + XSYMBOL_WITH_POS (o2)->sym, + equal_kind, depth + 1, ht) + && internal_equal (XSYMBOL_WITH_POS (o1)->pos, + XSYMBOL_WITH_POS (o2)->pos, + equal_kind, depth + 1, ht)); /* Aside from them, only true vectors, char-tables, compiled functions, and fonts (font-spec, font-entity, font-object) -- Alan Mackenzie (Nuremberg, Germany).