diff options
| author | Mattias EngdegÄrd | 2024-03-06 12:03:06 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2024-03-07 13:47:53 +0100 |
| commit | 61b2f5f96b1d9dfd2fd908e09fac0d4163049c42 (patch) | |
| tree | e76095045e99141e287be64920502e053de5a787 | |
| parent | 8aabd835747297818d538cc16b3f53fcc1dd67f6 (diff) | |
| download | emacs-61b2f5f96b1d9dfd2fd908e09fac0d4163049c42.tar.gz emacs-61b2f5f96b1d9dfd2fd908e09fac0d4163049c42.zip | |
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.
| -rw-r--r-- | doc/lispref/functions.texi | 13 | ||||
| -rw-r--r-- | etc/NEWS | 16 | ||||
| -rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 9 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/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 | |||
| 498 | nice in the source code will look ugly when displayed by the help | 498 | nice in the source code will look ugly when displayed by the help |
| 499 | commands. | 499 | commands. |
| 500 | 500 | ||
| 501 | You may wonder how the documentation string could be optional, since | 501 | A documentation string must always be followed by at least one Lisp |
| 502 | there are required components of the function that follow it (the body). | 502 | expression; otherwise, it is not a documentation string at all but the |
| 503 | Since evaluation of a string returns that string, without any side effects, | 503 | single expression of the body and used as the return value. |
| 504 | it has no effect if it is not the last form in the body. Thus, in | 504 | When there is no meaningful value to return from a function, it is |
| 505 | practice, there is no confusion between the first form of the body and the | 505 | standard practice to return @code{nil} by adding it after the |
| 506 | documentation string; if the only body form is a string then it serves both | 506 | documentation string. |
| 507 | as the return value and as the documentation. | ||
| 508 | 507 | ||
| 509 | The last line of the documentation string can specify calling | 508 | The last line of the documentation string can specify calling |
| 510 | conventions different from the actual function arguments. Write | 509 | conventions different from the actual function arguments. Write |
| @@ -1818,6 +1818,22 @@ Tree-sitter conditionally sets 'forward-sexp-function' for major modes | |||
| 1818 | that have defined 'sexp' in 'treesit-thing-settings' to enable | 1818 | that have defined 'sexp' in 'treesit-thing-settings' to enable |
| 1819 | sexp-related motion commands. | 1819 | sexp-related motion commands. |
| 1820 | 1820 | ||
| 1821 | +++ | ||
| 1822 | ** Returned strings are never docstrings. | ||
| 1823 | Functions and macros whose bodies consist of a single string literal now | ||
| 1824 | only return that string; it is not used as a docstring. Example: | ||
| 1825 | |||
| 1826 | (defun sing-a-song () | ||
| 1827 | "Sing a song.") | ||
| 1828 | |||
| 1829 | The above function returns the string '"Sing a song."' but has no | ||
| 1830 | docstring. Previously, that string was used as both a docstring and | ||
| 1831 | return value, which was never what the programmer wanted. If you want | ||
| 1832 | the string to be a docstring, add an explicit return value. | ||
| 1833 | |||
| 1834 | This change applies to 'defun', 'defsubst', 'defmacro' and 'lambda' | ||
| 1835 | forms; other defining forms such as 'cl-defun' already worked this way. | ||
| 1836 | |||
| 1821 | ** New or changed byte-compilation warnings | 1837 | ** New or changed byte-compilation warnings |
| 1822 | 1838 | ||
| 1823 | --- | 1839 | --- |
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." | |||
| 3061 | (append (if (not lexical-binding) arglistvars) | 3061 | (append (if (not lexical-binding) arglistvars) |
| 3062 | byte-compile-bound-variables)) | 3062 | byte-compile-bound-variables)) |
| 3063 | (body (cdr (cdr fun))) | 3063 | (body (cdr (cdr fun))) |
| 3064 | (doc (if (stringp (car body)) | 3064 | ;; Treat a final string literal as a value, not a doc string. |
| 3065 | (doc (if (and (cdr body) (stringp (car body))) | ||
| 3065 | (prog1 (car body) | 3066 | (prog1 (car body) |
| 3066 | ;; Discard the doc string from the body | 3067 | ;; Discard the doc string from the body. |
| 3067 | ;; unless it is the last element of the body. | 3068 | (setq body (cdr body))))) |
| 3068 | (if (cdr body) | ||
| 3069 | (setq body (cdr body)))))) | ||
| 3070 | (int (assq 'interactive body)) | 3069 | (int (assq 'interactive body)) |
| 3071 | command-modes) | 3070 | command-modes) |
| 3072 | (when lexical-binding | 3071 | (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 @@ | |||
| 1 | ;;; -*- lexical-binding: t -*- | 1 | ;;; -*- lexical-binding: t -*- |
| 2 | (defun foo () | 2 | (defun foo () |
| 3 | "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") | 3 | "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |
| 4 | nil) | ||