diff --git a/ChangeLog b/ChangeLog index 4ae5cbbdf..523b9d97c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2019-12-22 Daniel Shahaf + * 45111: Doc/Zsh/grammar.yo, Etc/BUGS, NEWS, + Test/A01grammar.ztst: zshmisc(1): Clarify the documentation of + 'return' and 'exit' in conjunction with try/always + * 45112: Doc/Zsh/mod_zutil.yo: zshmodules: Explicitly document the return values of the 'zstyle' getters -s, -b, and -a. diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo index d30c9d2d7..a66358ed6 100644 --- a/Doc/Zsh/grammar.yo +++ b/Doc/Zsh/grammar.yo @@ -297,11 +297,11 @@ findex(always) cindex(always blocks) cindex(try blocks) item(tt({) var(try-list) tt(} always {) var(always-list) tt(}))( -First execute var(try-list). Regardless of errors, or tt(break), -tt(continue), or tt(return) commands encountered within var(try-list), +First execute var(try-list). Regardless of errors, or tt(break) or +tt(continue) commands encountered within var(try-list), execute var(always-list). Execution then continues from the result of the execution of var(try-list); in other words, any error, -or tt(break), tt(continue), or tt(return) command is treated in the +or tt(break) or tt(continue) command is treated in the normal way, as if var(always-list) were not present. The two chunks of code are referred to as the `try block' and the `always block'. @@ -345,10 +345,16 @@ example({ } # The error condition has been reset.) -An tt(exit) command (or a tt(return) command executed at the outermost -function level of a script) encountered in tt(try-list) does em(not) cause +When a tt(try) block occurs outside of any function, +a tt(return) or a tt(exit) encountered in var(try-list) does em(not) cause the execution of var(always-list). Instead, the shell exits immediately after any tt(EXIT) trap has been executed. +Otherwise, a tt(return) command encountered in var(try-list) will cause the +execution of var(always-list), just like tt(break) and tt(continue). + +COMMENT(The semantics of calling 'exit' in try-list inside a function are +deliberately left unspecified, because historically there was a mismatch between +the documented and implemented behaviours. Cf. 20076, 21734/21735, 45075.) ) findex(function) xitem(tt(function) var(word) ... [ tt(()) ] [ var(term) ] tt({) var(list) tt(})) diff --git a/Etc/BUGS b/Etc/BUGS index 8244677f6..3fbe81831 100644 --- a/Etc/BUGS +++ b/Etc/BUGS @@ -39,6 +39,3 @@ fn trap1 trap2 echo out2 ]]] ------------------------------------------------------------------------ -45075 - Daniel Shahaf - '{ exit } always { foo }' - docs/code mismatch -and return/exit differences ------------------------------------------------------------------------- diff --git a/NEWS b/NEWS index c1322ed0f..af59cb4e6 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,16 @@ path the leading '/' counts as one component. The functions builtin gained a -c option to efficiently copy functions. +The zshmisc(1) manual page incorrectly stated that when 'exit' is used +in a `try' block inside a function, the corresponding `always' block will +be executed. The manual page has been corrected. The shell's behaviour +has not changed, but code such as the following: +. + f() { { exit } always { echo Hello world } } +. +should be changed either to use 'return' instead of 'exit', or to have +the try/always block outside of any function. + Changes from 5.6.2 to 5.7.1 --------------------------- diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst index 2649c29c8..d3a591761 100644 --- a/Test/A01grammar.ztst +++ b/Test/A01grammar.ztst @@ -729,6 +729,7 @@ 3:Exit and always block with functions: simple >BEGIN >END +F:Note that the behaviour of 'exit' inside try-list inside a function is unspecified. ( mytrue() { echo mytrue; return 0 } @@ -741,6 +742,7 @@ >BEGIN >mytrue >END +F:Note that the behaviour of 'exit' inside try-list inside a function is unspecified. (emulate sh -c ' fn() {