emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 61b2f5f96b1 1/2: Single string literal in body is return value on


From: Mattias Engdegård
Subject: master 61b2f5f96b1 1/2: Single string literal in body is return value only, not doc string
Date: Thu, 7 Mar 2024 09:04:05 -0500 (EST)

branch: master
commit 61b2f5f96b1d9dfd2fd908e09fac0d4163049c42
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    Single string literal in body is return value only, not doc string
    
    A function or macro body consisting of a single string literal now only
    uses it as a return value.  Previously, it had the dual uses as return
    value and doc string, which was never what the programmer wanted and
    had some inconvenient consequences (bug#69387).
    
    This change applies to `lambda`, `defun`, `defsubst` and `defmacro`
    forms; most other defining forms already worked in the sensible way.
    
    * lisp/emacs-lisp/bytecomp.el (byte-compile-lambda):
    Don't use a lone string literal as doc string.
    * test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defun.el
    (foo): Update docstring warning test.
    * doc/lispref/functions.texi (Function Documentation): Update.
    * etc/NEWS: Announce.
---
 doc/lispref/functions.texi                               | 13 ++++++-------
 etc/NEWS                                                 | 16 ++++++++++++++++
 lisp/emacs-lisp/bytecomp.el                              |  9 ++++-----
 .../bytecomp-resources/warn-wide-docstring-defun.el      |  3 ++-
 4 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index 344b3ff3a50..ff635fc54b2 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -498,13 +498,12 @@ indentation of the following lines is inside the string; 
what looks
 nice in the source code will look ugly when displayed by the help
 commands.
 
-  You may wonder how the documentation string could be optional, since
-there are required components of the function that follow it (the body).
-Since evaluation of a string returns that string, without any side effects,
-it has no effect if it is not the last form in the body.  Thus, in
-practice, there is no confusion between the first form of the body and the
-documentation string; if the only body form is a string then it serves both
-as the return value and as the documentation.
+  A documentation string must always be followed by at least one Lisp
+expression; otherwise, it is not a documentation string at all but the
+single expression of the body and used as the return value.
+When there is no meaningful value to return from a function, it is
+standard practice to return @code{nil} by adding it after the
+documentation string.
 
   The last line of the documentation string can specify calling
 conventions different from the actual function arguments.  Write
diff --git a/etc/NEWS b/etc/NEWS
index 745b3b12936..3a57084688d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1818,6 +1818,22 @@ Tree-sitter conditionally sets 'forward-sexp-function' 
for major modes
 that have defined 'sexp' in 'treesit-thing-settings' to enable
 sexp-related motion commands.
 
++++
+** Returned strings are never docstrings.
+Functions and macros whose bodies consist of a single string literal now
+only return that string; it is not used as a docstring.  Example:
+
+    (defun sing-a-song ()
+      "Sing a song.")
+
+The above function returns the string '"Sing a song."' but has no
+docstring.  Previously, that string was used as both a docstring and
+return value, which was never what the programmer wanted.  If you want
+the string to be a docstring, add an explicit return value.
+
+This change applies to 'defun', 'defsubst', 'defmacro' and 'lambda'
+forms; other defining forms such as 'cl-defun' already worked this way.
+
 ** New or changed byte-compilation warnings
 
 ---
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index c3355eedd75..cf0e6d600dd 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -3061,12 +3061,11 @@ lambda-expression."
          (append (if (not lexical-binding) arglistvars)
                   byte-compile-bound-variables))
         (body (cdr (cdr fun)))
-        (doc (if (stringp (car body))
+         ;; Treat a final string literal as a value, not a doc string.
+        (doc (if (and (cdr body) (stringp (car body)))
                   (prog1 (car body)
-                    ;; Discard the doc string from the body
-                    ;; unless it is the last element of the body.
-                    (if (cdr body)
-                        (setq body (cdr body))))))
+                    ;; Discard the doc string from the body.
+                    (setq body (cdr body)))))
         (int (assq 'interactive body))
          command-modes)
     (when lexical-binding
diff --git 
a/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defun.el 
b/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defun.el
index 94b0e80c979..571f7f6f095 100644
--- a/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defun.el
+++ b/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-defun.el
@@ -1,3 +1,4 @@
 ;;; -*- lexical-binding: t -*-
 (defun foo ()
-  
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
+  
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+  nil)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]