From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Noam Postavsky Newsgroups: gmane.emacs.bugs Subject: bug#29165: 26.0.90; can't use some code byte-compiled under emacs 24 Date: Sat, 20 Jan 2018 17:10:17 -0500 Message-ID: <87po64npva.fsf@users.sourceforge.net> References: <6eh8u7x5be.fsf@just-testing.permabit.com> <87375r7f0g.fsf@users.sourceforge.net> <9f1e7a1f-bfc0-43a4-9acb-cf69b85587be@default> <5C8038D7-FF85-4C42-A728-F3F85CDAC85C@permabit.com> <87efpb46sp.fsf@linux-m68k.org> <3EB0E53F-4B99-44C2-9F2E-1125A33E408B@permabit.com> <87r2rvb7c2.fsf@users.sourceforge.net> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1516486177 18998 195.159.176.226 (20 Jan 2018 22:09:37 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 20 Jan 2018 22:09:37 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.90 (gnu/linux) Cc: Ken Raeburn , Andreas Schwab , Philipp Stephani , 29165@debbugs.gnu.org, Stefan Monnier To: Glenn Morris Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Jan 20 23:09:32 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 1ed1KB-0003sm-0A for geb-bug-gnu-emacs@m.gmane.org; Sat, 20 Jan 2018 23:09:19 +0100 Original-Received: from localhost ([::1]:39006 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ed1MB-0002tm-7F for geb-bug-gnu-emacs@m.gmane.org; Sat, 20 Jan 2018 17:11:23 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:58340) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ed1Lw-0002pK-1Q for bug-gnu-emacs@gnu.org; Sat, 20 Jan 2018 17:11:09 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ed1Lr-0001Gi-00 for bug-gnu-emacs@gnu.org; Sat, 20 Jan 2018 17:11:08 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:56742) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ed1Lq-0001GX-QI for bug-gnu-emacs@gnu.org; Sat, 20 Jan 2018 17:11:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1ed1Lq-0001W1-Hb for bug-gnu-emacs@gnu.org; Sat, 20 Jan 2018 17:11:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Jan 2018 22:11:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 29165 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: notabug Original-Received: via spool by 29165-submit@debbugs.gnu.org id=B29165.15164862305775 (code B ref 29165); Sat, 20 Jan 2018 22:11:02 +0000 Original-Received: (at 29165) by debbugs.gnu.org; 20 Jan 2018 22:10:30 +0000 Original-Received: from localhost ([127.0.0.1]:36406 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ed1LJ-0001Uz-Ts for submit@debbugs.gnu.org; Sat, 20 Jan 2018 17:10:30 -0500 Original-Received: from mail-io0-f181.google.com ([209.85.223.181]:46958) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ed1LH-0001UR-21; Sat, 20 Jan 2018 17:10:27 -0500 Original-Received: by mail-io0-f181.google.com with SMTP id f34so5737549ioi.13; Sat, 20 Jan 2018 14:10:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=MvfhXFOs5o8BjAjELc4KHgq6i1Fg5QaoABz/bmn9U2E=; b=EvBT7/coM8iJbIW9m5XE+2568kiAiDHqGALwy/E9GJZxLRPcsPFLPlhAE7/R/yZaKe yN475tzSbrpq3MBzYfl/lgpZk2X2iOglOPSvN/st27oIfRx4mGSy8mJ5F211WB8rFXc+ WmnDP6Yqi26cd3JDZGjnXS7EgnyuEbBDF9bum36xOrS6OBbDGlleM8YOaurpzcmR3/KZ bIbcS3PJByn9WAfHJN09B36QyahrQoF0WfajQDkPdnY+qyf6Dephk48ebZfbGMrJLhQw A13zXpQIf+kCZaPRAZtiAgC33hE35YCLn/V4lxMcap9Miv9Vwk95gWSE7YTneb//P/4G Y3xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:references:date :in-reply-to:message-id:user-agent:mime-version; bh=MvfhXFOs5o8BjAjELc4KHgq6i1Fg5QaoABz/bmn9U2E=; b=treCedKyqhRyS45WCgrwcCdzqdJ6d2F790gKya34OmY8laEkYhAdwAV0fXimlXzw5Y gqjnz+FvSBxC5qu43H2lGb3xDSv5BmLzEPxCfr0dnpf4lc02jEvaDvtklJd58jKPi3XX 5q/KksPtP1PPUkb/tSWNKG/FI4lWgEViEbV1R//QvdogYtGv7VXqdx2i4dM8AkH12EvH RXhCCqvqK6vz82y/Y1fe1oVt0CpGgYtUo3mRKH3JMxCOF8NwhWw5x7ibtC6Uy2GXgHcc S9OgfT/bcAk9/Gih/LNTQQUYrSY9juekDoXlGiAjeD4+bNoE5t+2PRh6ANFW4chIO7B7 0ddg== X-Gm-Message-State: AKwxytfPDKsxi/1s/XgibciK0kpUJ6bgQ/EwcsC68+ceKstpyNQ2Bj3J IJ18X/Yp6oS80RWa10Tw/M07GQ== X-Google-Smtp-Source: AH8x225v0QpdA4AlCofCO87KWB1jmH+tqeEqYthSQ/ql/5CqtftV98e34AeXPKSjrK0PPS+3183kjg== X-Received: by 10.107.69.3 with SMTP id s3mr3128751ioa.67.1516486221432; Sat, 20 Jan 2018 14:10:21 -0800 (PST) Original-Received: from zebian ([45.2.119.34]) by smtp.googlemail.com with ESMTPSA id l68sm2226874ith.25.2018.01.20.14.10.18 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 20 Jan 2018 14:10:19 -0800 (PST) In-Reply-To: <87r2rvb7c2.fsf@users.sourceforge.net> (Noam Postavsky's message of "Fri, 15 Dec 2017 23:54:53 -0500") 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:142335 Archived-At: --=-=-= Content-Type: text/plain tags 29165 = patch quit Noam Postavsky writes: > I've reverted my cl-lib code changes, so the conflict should be resolved > now. As for this bug, it seems the best way forward is to relax the > checks so that an empty list of &optional variables is accepted. Here's a patch. Details of behaviour changes over versions are in the commit message. I probably should have got around to this before 26.0.91, but I think this should still go to emacs-26 because the patch makes the behaviour closer to what was in v25. --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=v1-0001-Allow-rest-or-optional-without-following-variable.patch Content-Description: patch >From b019118586204357c3d20541724c63163eed695b Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 20 Jan 2018 11:27:23 -0500 Subject: [PATCH v1] Allow `&rest' or `&optional' without following variable (Bug#29165) This is sometimes convenient when writing macros, so that the empty variable case doesn't need to be handled specially. Older versions of Emacs accepted this in some cases. | arglist | i/c 25 | i/c 26.0.90 | i/c new | |---------------------------+--------+-------------+---------| | (&rest) | y/n | n/n | y/y | | (&rest &rest) | y/n | n/n | n/n | | (&rest &rest x) | y/n | n/n | n/n | | (&rest x &rest) | y/n | n/n | n/n | | (&rest x &rest y) | y/n | n/n | n/n | |---------------------------+--------+-------------+---------| | (&optional) | y/n | n/n | y/y | | (&optional &optional) | y/n | n/n | n/n | | (&optional x &optional) | y/n | n/n | n/n | | (&optional x &optional y) | y/y | n/n | n/n | |---------------------------+--------+-------------+---------| | (&optional &rest) | y/n | n/n | y/y | | (&optional x &rest) | y/n | n/n | y/y | | (&optional &rest y) | y/y | n/n | y/y | |---------------------------+--------+-------------+---------| | (&rest &optional) | y/n | n/n | n/n | | (&rest &optional y) | y/n | n/n | n/n | | (&rest x &optional y) | y/n | n/n | n/n | (require 'bytecomp) (defun ck-args (arglist) (insert (condition-case err (progn (funcall `(lambda ,arglist 'ok)) "y") (error (error-message-string err) "n")) "/" (condition-case err (progn (byte-compile-check-lambda-list arglist) "y") (error (error-message-string err) "n")))) (with-current-buffer (get-buffer-create "*ck-args*") (erase-buffer) (dolist (arglist '((&rest) (&rest &rest) (&rest &rest x) (&rest x &rest) (&rest x &rest y) (&optional) (&optional &optional) (&optional x &optional) (&optional x &optional y) (&optional &rest) (&optional x &rest) (&optional &rest y) (&rest &optional) (&rest &optional y) (&rest x &optional y))) (ck-args arglist) (insert "\n")) (display-buffer (current-buffer))) * src/eval.c (funcall_lambda): * lisp/emacs-lisp/bytecomp.el (byte-compile-check-lambda-list): Don't check for missing variables after `&rest' and `&optional'. * test/src/eval-tests.el (eval-tests--bugs-24912-and-24913) (eval-tests-accept-empty-optional-rest): Update tests accordingly. * etc/NEWS: Update announcement accordingly. --- etc/NEWS | 28 ++++++++++++++++++++++------ lisp/emacs-lisp/bytecomp.el | 11 ++++------- src/eval.c | 10 +++------- test/src/eval-tests.el | 20 +++++++++++++++++--- 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 67915c7024..f5859d7a60 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1493,15 +1493,31 @@ support, you should set 'eldoc-documentation-function' instead of calling 'eldoc-message' directly. --- -** Using '&rest' or '&optional' incorrectly is now an error. -For example giving '&optional' without a following variable, or -passing '&optional' multiple times: +** Emacs is now more consistent about use of '&rest' and '&optional'. + +--- +*** Using them twice is now an error. - (defun foo (&optional &rest x)) (defun bar (&optional &optional x)) + (defun bar (&rest &rest x)) + +Previously, Emacs ignored the extra keyword. + +--- +*** Putting '&optional' after '&rest' is now an error. + + (defun foo (&rest &optional x)) + +Previously, it was only a compilation error, but the interpreter +accepted it. + +--- +*** Omitting variables after '&optional' or '&rest' is now accepted. + + (defun foo (&optional)) -Previously, Emacs would just ignore the extra keyword, or give -incorrect results in certain cases. +Previously, it was accepted only in certain cases, e.g., '&optional' +if it was followed immediately by '&rest'. --- ** The pinentry.el library has been removed. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index eb00725776..222aca05f2 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2749,15 +2749,12 @@ byte-compile-check-lambda-list (macroexp--const-symbol-p arg t)) (error "Invalid lambda variable %s" arg)) ((eq arg '&rest) - (unless (cdr list) - (error "&rest without variable name")) (when (cddr list) - (error "Garbage following &rest VAR in lambda-list"))) + (error "Garbage following &rest VAR in lambda-list")) + (when (memq (cadr list) '(&optional &rest)) + (error "%s following &rest in lambda-list" (cadr list)))) ((eq arg '&optional) - (when (or (null (cdr list)) - (memq (cadr list) '(&optional &rest))) - (error "Variable name missing after &optional")) - (when (memq '&optional (cddr list)) + (when (memq '&optional (cdr list)) (error "Duplicate &optional"))) ((memq arg vars) (byte-compile-warn "repeated variable %s in lambda-list" arg)) diff --git a/src/eval.c b/src/eval.c index e05a17f7b4..9ec937f1a2 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2980,7 +2980,6 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, emacs_abort (); i = optional = rest = 0; - bool previous_optional_or_rest = false; for (; CONSP (syms_left); syms_left = XCDR (syms_left)) { maybe_quit (); @@ -2991,17 +2990,15 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, if (EQ (next, Qand_rest)) { - if (rest || previous_optional_or_rest) + if (rest) xsignal1 (Qinvalid_function, fun); rest = 1; - previous_optional_or_rest = true; } else if (EQ (next, Qand_optional)) { - if (optional || rest || previous_optional_or_rest) + if (optional || rest) xsignal1 (Qinvalid_function, fun); optional = 1; - previous_optional_or_rest = true; } else { @@ -3025,11 +3022,10 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, else /* Dynamically bind NEXT. */ specbind (next, arg); - previous_optional_or_rest = false; } } - if (!NILP (syms_left) || previous_optional_or_rest) + if (!NILP (syms_left)) xsignal1 (Qinvalid_function, fun); else if (i < nargs) xsignal2 (Qwrong_number_of_arguments, fun, make_number (nargs)); diff --git a/test/src/eval-tests.el b/test/src/eval-tests.el index 201382da9c..57faa0feae 100644 --- a/test/src/eval-tests.el +++ b/test/src/eval-tests.el @@ -37,8 +37,7 @@ byte-compile-debug (ert-deftest eval-tests--bugs-24912-and-24913 () "Check that Emacs doesn't accept weird argument lists. Bug#24912 and Bug#24913." - (dolist (args '((&optional) (&rest) (&optional &rest) (&rest &optional) - (&optional &rest a) (&optional a &rest) + (dolist (args '((&rest &optional) (&rest a &optional) (&rest &optional a) (&optional &optional) (&optional &optional a) (&optional a &optional b) @@ -47,7 +46,22 @@ byte-compile-debug (should-error (eval `(funcall (lambda ,args)) t) :type 'invalid-function) (should-error (byte-compile-check-lambda-list args)) (let ((byte-compile-debug t)) - (should-error (eval `(byte-compile (lambda ,args)) t))))) + (ert-info ((format "bytecomp: args = %S" args)) + (should-error (eval `(byte-compile (lambda ,args)) t)))))) + +(ert-deftest eval-tests-accept-empty-optional-rest () + "Check that Emacs accepts empty &optional and &rest arglists. +Bug#24912." + (dolist (args '((&optional) (&rest) (&optional &rest) + (&optional &rest a) (&optional a &rest))) + (let ((fun `(lambda ,args 'ok))) + (ert-info ("eval") + (should (eq (funcall (eval fun t)) 'ok))) + (ert-info ("byte comp check") + (byte-compile-check-lambda-list args)) + (ert-info ("bytecomp") + (let ((byte-compile-debug t)) + (should (eq (funcall (byte-compile fun)) 'ok))))))) (dolist (form '(let let*)) -- 2.11.0 --=-=-=--