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#28557: 26.0.60; Bugs using (:documentation FORM) in closures Date: Fri, 22 Sep 2017 10:30:11 -0700 Message-ID: <87o9q2od3w.fsf@runbox.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1506101539 32497 195.159.176.226 (22 Sep 2017 17:32:19 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 22 Sep 2017 17:32:19 +0000 (UTC) Cc: Stefan Monnier To: 28557@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Sep 22 19:32:13 2017 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 1dvRoB-0007sf-4V for geb-bug-gnu-emacs@m.gmane.org; Fri, 22 Sep 2017 19:32:11 +0200 Original-Received: from localhost ([::1]:60354 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvRoG-0004KX-Pc for geb-bug-gnu-emacs@m.gmane.org; Fri, 22 Sep 2017 13:32:16 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:35866) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvRo6-0004IL-Qg for bug-gnu-emacs@gnu.org; Fri, 22 Sep 2017 13:32:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dvRo4-0005qV-4B for bug-gnu-emacs@gnu.org; Fri, 22 Sep 2017 13:32:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:44483) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dvRo4-0005qM-0J for bug-gnu-emacs@gnu.org; Fri, 22 Sep 2017 13:32:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dvRo3-0001Ul-2T; Fri, 22 Sep 2017 13:32:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Gemini Lasswell Original-Sender: "Debbugs-submit" Resent-CC: monnier@IRO.UMontreal.CA, bug-gnu-emacs@gnu.org Resent-Date: Fri, 22 Sep 2017 17:32:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 28557 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: X-Debbugs-Original-To: bug-gnu-emacs@gnu.org X-Debbugs-Original-Xcc: Stefan Monnier Original-Received: via spool by submit@debbugs.gnu.org id=B.15061014805691 (code B ref -1); Fri, 22 Sep 2017 17:32:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 22 Sep 2017 17:31:20 +0000 Original-Received: from localhost ([127.0.0.1]:53162 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dvRnM-0001Ti-Dc for submit@debbugs.gnu.org; Fri, 22 Sep 2017 13:31:20 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:44665) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dvRnK-0001TV-Du for submit@debbugs.gnu.org; Fri, 22 Sep 2017 13:31:19 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dvRnD-0005Gy-HY for submit@debbugs.gnu.org; Fri, 22 Sep 2017 13:31:13 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:46729) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dvRnD-0005Gr-DV for submit@debbugs.gnu.org; Fri, 22 Sep 2017 13:31:11 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:35605) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dvRnB-000419-Ak for bug-gnu-emacs@gnu.org; Fri, 22 Sep 2017 13:31:11 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dvRn8-0005D3-Lu for bug-gnu-emacs@gnu.org; Fri, 22 Sep 2017 13:31:09 -0400 Original-Received: from aibo.runbox.com ([91.220.196.211]:50768) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dvRn8-0005BD-4p for bug-gnu-emacs@gnu.org; Fri, 22 Sep 2017 13:31:06 -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:Date:Subject:To:From; bh=nKk5PtkMFXZx2Tmy1q+nCN0V1JemuGJ2OZ9foyWXda4=; b=Au0dUfW93phM39VtTKYLxjr2g tbxM+wKk6pmqzXqqjIp2HB6XzjCEMg17EPZDcyOa76QdD4//rzXxxeubpYyOFnrBZm37AqErCZAg3 5qyna46+m93F0XHNoQZL6yCdWPDcuBVl2EGDh1v5kzOm97DzKJiVnl92I/k/Jyv5jpC3ZLZqawkiu tI1KIMS1NHboxFGbhJrCKOLWOm1qSYAfZ9Ht2ML5q+8FwlmQZsUji6VY75E++2yAIdeGgHDO6bMJC Ua1Z5dVVJqdg9MOhpmh++WZiOk+SRm7sdmlXFhSSxT3ZQ1mQiXKjTM0LiSPn0u1+JKBJaUa+mBKwY vFYNuXMgw==; Original-Received: from [10.9.9.210] (helo=mailfront10.runbox.com) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1dvRn3-0005uI-KD for bug-gnu-emacs@gnu.org; Fri, 22 Sep 2017 19:31:01 +0200 Original-Received: from c-24-22-244-161.hsd1.wa.comcast.net ([24.22.244.161] helo=chinook) by mailfront10.runbox.com with esmtpsa (uid:179284 ) (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) id 1dvRmO-0001Oo-Jr for bug-gnu-emacs@gnu.org; Fri, 22 Sep 2017 19:30:21 +0200 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x 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:137246 Archived-At: --=-=-= Content-Type: text/plain Since Emacs 25, docstrings can be constructed using (:documentation FORM) in closures, when lexical-binding is on. This isn't documented except in NEWS. Bug #24773 is about Edebug specs which have not been updated to recognize :documentation. I'd like to fix it, so I started trying to figure out which macros accept :documentation forms so I would know which Edebug specs to update, and that effort turned into a collection of tests for the feature, see attached: --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=cconv-tests.el ;;; cconv-tests.el --- Tests for cconv.el functionality -*- lexical-binding: t; -*- ;; Copyright (C) 2017 Free Software Foundation, Inc. ;; Author: Gemini Lasswell ;; This file is part of GNU Emacs. ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . ;;; Commentary: ;;; Code: (require 'ert) (require 'cl-lib) (ert-deftest cconv-tests-lambda-:documentation () "Docstring for lambda can be specified with :documentation." (let ((fun (lambda () (:documentation (concat "lambda" " documentation")) 'lambda-result))) (should (string= (documentation fun) "lambda documentation")) (should (eq (funcall fun) 'lambda-result)))) (ert-deftest cconv-tests-pcase-lambda-:documentation () "Docstring for pcase-lambda can be specified with :documentation." (let ((fun (pcase-lambda (`(,a ,b)) (:documentation (concat "pcase-lambda" " documentation")) (list b a)))) (should (string= (documentation fun) "pcase-lambda documentation")) (should (equal '(2 1) (funcall fun '(1 2)))))) (defun cconv-tests-defun () (:documentation (concat "defun" " documentation")) 'defun-result) (ert-deftest cconv-tests-defun-:documentation () "Docstring for defun can be specified with :documentation." (should (string= (documentation 'cconv-tests-defun) "defun documentation")) (should (eq (cconv-tests-defun) 'defun-result))) (cl-defun cconv-tests-cl-defun () (:documentation (concat "cl-defun" " documentation")) 'cl-defun-result) (ert-deftest cconv-tests-cl-defun-:documentation () "Docstring for cl-defun can be specified with :documentation." (should (string= (documentation 'cconv-tests-cl-defun) "cl-defun documentation")) (should (eq (cconv-tests-cl-defun) 'cl-defun-result))) (defmacro cconv-tests-defmacro () (:documentation (concat "defmacro" " documentation")) '(quote defmacro-result)) (ert-deftest cconv-tests-defmacro-:documentation () "Docstring for defmacro can be specified with :documentation." (should (string= (documentation 'cconv-tests-defmacro) "defmacro documentation")) (should (eq (cconv-tests-defmacro) 'defmacro-result))) (cl-defmacro cconv-tests-cl-defmacro () (:documentation (concat "cl-defmacro" " documentation")) '(quote cl-defmacro-result)) (ert-deftest cconv-tests-cl-defmacro-:documentation () "Docstring for cl-defmacro can be specified with :documentation." (should (string= (documentation 'cconv-tests-cl-defmacro) "cl-defmacro documentation")) (should (eq (cconv-tests-cl-defmacro) 'cl-defmacro-result))) (cl-iter-defun cconv-tests-cl-iter-defun () (:documentation (concat "cl-iter-defun" " documentation")) (iter-yield 'cl-iter-defun-result)) (ert-deftest cconv-tests-cl-iter-defun-:documentation () "Docstring for cl-iter-defun can be specified with :documentation." (should (string= (documentation 'cconv-tests-cl-iter-defun) "cl-iter-defun documentation")) (should (eq (iter-next (cconv-tests-cl-iter-defun)) 'cl-iter-defun-result))) (iter-defun cconv-tests-iter-defun () (:documentation (concat "iter-defun" " documentation")) (iter-yield 'iter-defun-result)) (ert-deftest cconv-tests-iter-defun-:documentation () "Docstring for iter-defun can be specified with :documentation." (should (string= (documentation 'cconv-tests-iter-defun) "iter-defun documentation")) (should (eq (iter-next (cconv-tests-iter-defun)) 'iter-defun-result))) (ert-deftest cconv-tests-iter-lambda-:documentation () "Docstring for iter-lambda can be specified with :documentation." (let ((iter-fun (iter-lambda () (:documentation (concat "iter-lambda" " documentation")) (iter-yield 'iter-lambda-result)))) (should (string= (documentation iter-fun) "iter-lambda documentation")) (should (eq (iter-next (funcall iter-fun)) 'iter-lambda-result)))) (ert-deftest cconv-tests-cl-function-:documentation () "Docstring for cl-function can be specified with :documentation." (let ((fun (cl-function (lambda (&key arg) (:documentation (concat "cl-function" " documentation")) (list arg 'cl-function-result))))) (should (string= (documentation fun) "cl-function documentation")) (should (equal (funcall fun :arg t) '(t cl-function-result))))) (ert-deftest cconv-tests-function-:documentation () "Docstring for lambda inside function can be specified with :documentation." (let ((fun #'(lambda (arg) (:documentation (concat "function" " documentation")) (list arg 'function-result)))) (should (string= (documentation fun) "function documentation")) (should (equal (funcall fun t) '(t function-result))))) (fmakunbound 'cconv-tests-cl-defgeneric) (setplist 'cconv-tests-cl-defgeneric nil) (cl-defgeneric cconv-tests-cl-defgeneric (n) (:documentation (concat "cl-defgeneric" " documentation"))) (cl-defmethod cconv-tests-cl-defgeneric ((n integer)) (:documentation (concat "cl-defmethod" " documentation")) (+ 1 n)) (ert-deftest cconv-tests-cl-defgeneric-:documentation () "Docstring for cl-defgeneric can be specified with :documentation." (let ((descr (describe-function 'cconv-tests-cl-defgeneric))) (set-text-properties 0 (length descr) nil descr) (should (string-match-p "cl-defgeneric documentation" descr)) (should (string-match-p "cl-defmethod documentation" descr))) (should (= 11 (cconv-tests-cl-defgeneric 10)))) (fmakunbound 'cconv-tests-cl-defgeneric-literal) (setplist 'cconv-tests-cl-defgeneric-literal nil) (cl-defgeneric cconv-tests-cl-defgeneric-literal (n) (:documentation "cl-defgeneric-literal documentation")) (cl-defmethod cconv-tests-cl-defgeneric-literal ((n integer)) (:documentation "cl-defmethod-literal documentation") (+ 1 n)) (ert-deftest cconv-tests-cl-defgeneric-literal-:documentation () "Docstring for cl-defgeneric can be specified with :documentation." (let ((descr (describe-function 'cconv-tests-cl-defgeneric-literal))) (set-text-properties 0 (length descr) nil descr) (should (string-match-p "cl-defgeneric-literal documentation" descr)) (should (string-match-p "cl-defmethod-literal documentation" descr))) (should (= 11 (cconv-tests-cl-defgeneric-literal 10)))) (defsubst cconv-tests-defsubst () (:documentation (concat "defsubst" " documentation")) 'defsubst-result) (ert-deftest cconv-tests-defsubst-:documentation () "Docstring for defsubst can be specified with :documentation." (should (string= (documentation 'cconv-tests-defsubst) "defsubst documentation")) (should (eq (cconv-tests-defsubst) 'defsubst-result))) (cl-defsubst cconv-tests-cl-defsubst () (:documentation (concat "cl-defsubst" " documentation")) 'cl-defsubst-result) (ert-deftest cconv-tests-cl-defsubst-:documentation () "Docstring for cl-defsubst can be specified with :documentation." (should (string= (documentation 'cconv-tests-cl-defsubst) "cl-defsubst documentation")) (should (eq (cconv-tests-cl-defsubst) 'cl-defsubst-result))) (provide 'cconv-tests) ;;; cconv-tests.el ends here --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable While doing this I found these bugs: 1. A lambda wrapped by cl-function with a :documentation form will not get a docstring and the :documentation form will be left in the body of the closure. 2. In code run interactively, a :documentation form in cl-defmacro or defmacro will work correctly. However if you byte-compile that code, the byte-compiler stops with the following error message: Symbol=E2=80=99s function definition is void: internal-make-closure 3. A :documentation form in cl-defgeneric only works if its argument is a string literal. In cl-defmethod, it works whether the argument is a string literal or an expression. 4. A :documentation form works in cl-iter-defun and iter-defun, but not in iter-lambda. Stefan, here's a list of macros in which it appears to me that (:documentation FORM) is supposed to work. Is this correct? Am I missing any? lambda pcase-lambda defun defmacro cl-defun cl-defmacro iter-defun cl-iter-defun iter-lambda function cl-function cl-defgeneric cl-defmethod defsubst cl-defsubst --=-=-=--