spec changes for panic and recover. R=rsc, gri CC=golang-dev https://golang.org/cl/763041
diff --git a/doc/go_spec.html b/doc/go_spec.html index 828afd8..46dc33e 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html
@@ -1108,7 +1108,7 @@ key type; thus the key type must be a boolean, numeric, string, pointer, function, interface, map, or channel type. If the key type is an interface type, these comparison operators must be defined for the dynamic key values; -failure will cause a run-time error. +failure will cause a <a href="#Run_time_panics">run-time panic</a>. </p> @@ -2397,7 +2397,8 @@ <li><code>x</code> must be an integer value and <code>0 <= x < len(a)</code></li> <li><code>a[x]</code> is the array element at index <code>x</code> and the type of <code>a[x]</code> is the element type of <code>A</code></li> - <li>if the index <code>x</code> is out of range, a run-time exception occurs</li> + <li>if the index <code>x</code> is out of range, + a <a href="#Run_time_panics">run-time panic</a> occurs</li> </ul> <p> @@ -2409,7 +2410,8 @@ <li><code>a[x]</code> is the byte at index <code>x</code> and the type of <code>a[x]</code> is <code>byte</code></li> <li><code>a[x]</code> may not be assigned to - <li>if the index <code>x</code> is out of range, a run-time exception occurs</li> + <li>if the index <code>x</code> is out of range, + a <a href="#Run_time_panics">run-time panic</a> occurs</li> </ul> <p> @@ -2542,8 +2544,9 @@ </p> <p> If the type assertion holds, the value of the expression is the value -stored in <code>x</code> and its type is <code>T</code>. If the type assertion is false, a run-time -exception occurs. In other words, even though the dynamic type of <code>x</code> +stored in <code>x</code> and its type is <code>T</code>. If the type assertion is false, +a <a href="#Run_time_panics">run-time panic</a> occurs. +In other words, even though the dynamic type of <code>x</code> is known only at run-time, the type of <code>x.(T)</code> is known to be <code>T</code> in a correct program. </p> @@ -2562,7 +2565,7 @@ If the assertion holds, the expression returns the pair <code>(x.(T), true)</code>; otherwise, the expression returns <code>(Z, false)</code> where <code>Z</code> is the <a href="#The_zero_value">zero value</a> for type <code>T</code>. -No run-time exception occurs in this case. +No run-time panic occurs in this case. The type assertion in this construct thus acts like a function call returning a value and a boolean indicating success. (§<a href="#Assignments">Assignments</a>) </p> @@ -4281,7 +4284,7 @@ immediately before the surrounding function returns, after the return values, if any, have been evaluated, but before they are returned to the caller. For instance, if the deferred function is -a <a href="#Function_literals">function literal<a/> and the surrounding +a <a href="#Function_literals">function literal</a> and the surrounding function has <a href="#Function_types">named result parameters</a> that are in scope within the literal, the deferred function may access and modify the result parameters before they are returned. @@ -4510,6 +4513,150 @@ var rl = real(c64) // type float32 </pre> +<h3 id="Handling_panics">Handling panics</h3> + +<p> Two built-in functions, <code>panic</code> and <code>recover</code>, +assist in reporting and handling <a href="#Run_time_panics">run-time panics</a> +and program-defined error conditions. +</p> + +<pre class="grammar"> +func panic(interface{}) +func recover() interface{} +</pre> + +<p> +<font color=red>TODO: Most of this text could move to the respective +comments in <code>runtime.go</code> once the functions are implemented. +They are here, at least for now, for reference and discussion. +</font> +</p> + +<p> +When a function <code>F</code> calls <code>panic</code>, normal +execution of <code>F</code> stops immediately. Any functions whose +execution was <a href="#Defer_statements">deferred</a> by the +invocation of <code>F</code> are run in the usual way, and then +<code>F</code> returns to its caller. To the caller, <code>F</code> +then behaves like a call to <code>panic</code>, terminating its own +execution and running deferred functions. This continues until all +functions in the goroutine have ceased execution, in reverse order. +At that point, the program is +terminated and the error condition is reported, including the value of +the argument to <code>panic</code>. This termination sequence is +called <i>panicking</i>. +</p> + +<p> +The <code>recover</code> function allows a program to manage behavior +of a panicking goroutine. Executing a <code>recover</code> call +inside a deferred function (but not any function called by it) stops +the panicking sequence by restoring normal execution, and retrieves +the error value passed to the call of <code>panic</code>. If +<code>recover</code> is called outside the deferred function it will +not stop a panicking sequence. In this case, and when the goroutine +is not panicking, <code>recover</code> returns <code>nil</code>. +</p> + +<p> +If the function defined here, +</p> + +<pre> +func f(hideErrors bool) { + defer func() { + if x := recover(); x != nil { + println("panicking with value", v) + if !hideErrors { + panic(x) // go back to panicking + } + } + println("function returns normally") // executes only when hideErrors==true + }() + println("before") + p() + println("after") // never executes +} + +func p() { + panic(3) +} +</pre> + +<p> +is called with <code>hideErrors=true</code>, it prints +</p> + +<pre> +before +panicking with value 3 +function returns normally +</pre> + +<p> +and resumes normal execution in the function that called <code>f</code>. Otherwise, it prints +</p> + +<pre> +before +panicking with value 3 +</pre> + +<p> +and, absent further <code>recover</code> calls, terminates the program. +</p> + +<p> +Since deferred functions run before assigning the return values to the caller +of the deferring function, a deferred invocation of a function literal may modify the +invoking function's return values in the event of a panic. This permits a function to protect its +caller from panics that occur in functions it calls. +</p> + +<pre> +func IsPrintable(s string) (ok bool) { + ok = true + defer func() { + if recover() != nil { + println("input is not printable") + ok = false + } + // Panicking has stopped; execution will resume normally in caller. + // The return value will be true normally, false if a panic occurred. + } + panicIfNotPrintable(s) // will panic if validations fails. +} +</pre> + +<!--- +<p> +A deferred function that calls <code>recover</code> will see the +argument passed to <code>panic</code>. However, functions called +<i>from</i> the deferred function run normally, without behaving as +though they are panicking. This allows deferred code to run normally +in case recovery is necessary and guarantees that functions that manage +their own panics will not fail incorrectly. The function +</p> + +<pre> +func g() { + s := ReadString() + defer func() { + if IsPrintable(s) { + println("finished processing", s) + } else { + println("finished processing unprintable string") + } + }() + Analyze(s) +} +</pre> + +<p> +will not cause <code>IsPrintable</code> to print <code>"input is not printable"</code> +due to a <code>panic</code> triggered by the call to <code>Analyze</code>. +</p> +--> <h3 id="Bootstrapping">Bootstrapping</h3> @@ -4524,7 +4671,6 @@ print prints all arguments; formatting of arguments is implementation-specific println like print but prints spaces between arguments and a newline at the end -panic like print, aborts execution after printing </pre> @@ -4822,6 +4968,28 @@ is not imported by any other package. </p> +<h2 id="Run_time_errors">Run-time panics</h2> + +<p> +Execution errors such as attempting to index an array out +of bounds trigger a <i>run-time panic</i> equivalent to a call of +the built-in function <a href="#Handling_panics"><code>panic</code></a> +with a value of the implementation-defined interface type <code>runtime.Error</code>. +That type defines at least the method +<code>String() string</code>. The exact error values that +represent distinct run-time error conditions are unspecified, +at least for now. +</p> + +<pre> +package runtime + +type Error interface { + String() string + // and perhaps others +} +</pre> + <h2 id="System_considerations">System considerations</h2> <h3 id="Package_unsafe">Package <code>unsafe</code></h3> @@ -4942,4 +5110,6 @@ <li><span class="alert">Gccgo allows only one init() function per source file.</span></li> <li><span class="alert">Deferred functions cannot access the surrounding function's result parameters.</span></li> <li><span class="alert">Function results are not addressable.</span></li> + <li><span class="alert">Recover is not implemented.</span></li> + <li><span class="alert">The implemented version of panic differs from its specification.</span></li> </ul>