Commit ea7c57a0 authored by Robert Griesemer's avatar Robert Griesemer

go spec: restrictions for index and slice expressions

At the moment, gc and gccgo report compile-
time errors for certain constant indexes that
are out of bounds. The spec however requests
a run-time panic for out-of-bounds indexes
(http://tip.golang.org/ref/spec#Indexes).

Document the status quo.

Fixes #4231.

R=r, rsc, iant, ken
CC=golang-dev
https://golang.org/cl/6699048
parent a2659aa6
<!--{ <!--{
"Title": "The Go Programming Language Specification", "Title": "The Go Programming Language Specification",
"Subtitle": "Version of October 12, 2012", "Subtitle": "Version of October 17, 2012",
"Path": "/ref/spec" "Path": "/ref/spec"
}--> }-->
...@@ -663,7 +663,7 @@ type literals. ...@@ -663,7 +663,7 @@ type literals.
The <i>static type</i> (or just <i>type</i>) of a variable is the The <i>static type</i> (or just <i>type</i>) of a variable is the
type defined by its declaration. Variables of interface type type defined by its declaration. Variables of interface type
also have a distinct <i>dynamic type</i>, which also have a distinct <i>dynamic type</i>, which
is the actual type of the value stored in the variable at run-time. is the actual type of the value stored in the variable at run time.
The dynamic type may vary during execution but is always The dynamic type may vary during execution but is always
<a href="#Assignability">assignable</a> <a href="#Assignability">assignable</a>
to the static type of the interface variable. For non-interface to the static type of the interface variable. For non-interface
...@@ -2495,15 +2495,29 @@ rules apply: ...@@ -2495,15 +2495,29 @@ rules apply:
<p> <p>
For <code>a</code> of type <code>A</code> or <code>*A</code> For <code>a</code> of type <code>A</code> or <code>*A</code>
where <code>A</code> is an <a href="#Array_types">array type</a>, where <code>A</code> is an <a href="#Array_types">array type</a>:
or for <code>a</code> of type <code>S</code> where <code>S</code> is a <a href="#Slice_types">slice type</a>:
</p> </p>
<ul> <ul>
<li><code>x</code> must be an integer value and <code>0 &lt;= x &lt; len(a)</code></li> <li><code>x</code> must be an integer value; it is <i>in range</i> if <code>0 &lt;= x &lt; len(a)</code>,
otherwise it is <i>out of range</i></li>
<li>a <a href="#Constants">constant</a> index must be in range</li>
<li>if <code>a</code> is <code>nil</code> or if <code>x</code> is out of range at run time,
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
<li><code>a[x]</code> is the array element at index <code>x</code> and the type of <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> <code>a[x]</code> is the element type of <code>A</code></li>
<li>if <code>a</code> is <code>nil</code> or if the index <code>x</code> is out of range, </ul>
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
<p>
For <code>a</code> of type <code>S</code> where <code>S</code> is a <a href="#Slice_types">slice type</a>:
</p>
<ul>
<li><code>x</code> must be an integer value; it is <i>in range</i> if <code>0 &lt;= x &lt; len(a)</code>,
otherwise it is <i>out of range</i></li>
<li>a <a href="#Constants">constant</a> index must not be negative</li>
<li>if the slice is <code>nil</code> or if <code>x</code> is out of range at run time,
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
<li><code>a[x]</code> is the slice element at index <code>x</code> and the type of
<code>a[x]</code> is the element type of <code>S</code></li>
</ul> </ul>
<p> <p>
...@@ -2511,12 +2525,15 @@ For <code>a</code> of type <code>T</code> ...@@ -2511,12 +2525,15 @@ For <code>a</code> of type <code>T</code>
where <code>T</code> is a <a href="#String_types">string type</a>: where <code>T</code> is a <a href="#String_types">string type</a>:
</p> </p>
<ul> <ul>
<li><code>x</code> must be an integer value and <code>0 &lt;= x &lt; len(a)</code></li> <li><code>x</code> must be an integer value; it is <i>in range</i> if <code>0 &lt;= x &lt; len(a)</code>,
otherwise it is <i>out of range</i></li>
<li>a <a href="#Constants">constant</a> index must not be negative, and it must be in range
if the string <code>a</code> is also constant</li>
<li>if <code>x</code> is out of range at run time,
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
<li><code>a[x]</code> is the byte at index <code>x</code> and the type of <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> <code>a[x]</code> is <code>byte</code></li>
<li><code>a[x]</code> may not be assigned to</li> <li><code>a[x]</code> may not be assigned to</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> </ul>
<p> <p>
...@@ -2577,7 +2594,7 @@ a[low : high] ...@@ -2577,7 +2594,7 @@ a[low : high]
<p> <p>
constructs a substring or slice. The index expressions <code>low</code> and constructs a substring or slice. The index expressions <code>low</code> and
<code>high</code> select which elements appear in the result. The result has <code>high</code> select which elements appear in the result. The result has
indexes starting at 0 and length equal to indices starting at 0 and length equal to
<code>high</code>&nbsp;-&nbsp;<code>low</code>. <code>high</code>&nbsp;-&nbsp;<code>low</code>.
After slicing the array <code>a</code> After slicing the array <code>a</code>
</p> </p>
...@@ -2610,9 +2627,13 @@ a[:] // same as a[0 : len(a)] ...@@ -2610,9 +2627,13 @@ a[:] // same as a[0 : len(a)]
</pre> </pre>
<p> <p>
For arrays or strings, the indexes <code>low</code> and <code>high</code> must For arrays or strings, the indices <code>low</code> and <code>high</code> are
satisfy 0 &lt;= <code>low</code> &lt;= <code>high</code> &lt;= length; for <i>in range</i> if <code>0 &lt;= <code>low</code> &lt;= <code>high</code> &lt;= len(a)</code>,
slices, the upper bound is the capacity rather than the length. otherwise they are <i>out of range</i>.
For slices, the upper index bound is the slice capacity <code>cap(a)</code> rather than the length.
A <a href="#Constant_expressions">constant</a> index must not be negative, and if both indices
are constant, they must satisfy <code>low &lt;= high</code>. If <code>a</code> is <code>nil</code>
or if the indices are out of range at run time, a <a href="#Run_time_panics">run-time panic</a> occurs.
</p> </p>
<p> <p>
...@@ -2651,7 +2672,7 @@ If the type assertion holds, the value of the expression is the value ...@@ -2651,7 +2672,7 @@ 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, 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. a <a href="#Run_time_panics">run-time panic</a> occurs.
In other words, even though the dynamic type of <code>x</code> 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 is known only at run time, the type of <code>x.(T)</code> is
known to be <code>T</code> in a correct program. known to be <code>T</code> in a correct program.
</p> </p>
<p> <p>
...@@ -3604,7 +3625,7 @@ MyRunes("白鵬翔") // []rune{0x767d, 0x9d6c, 0x7fd4} ...@@ -3604,7 +3625,7 @@ MyRunes("白鵬翔") // []rune{0x767d, 0x9d6c, 0x7fd4}
<p> <p>
Constant expressions may contain only <a href="#Constants">constant</a> Constant expressions may contain only <a href="#Constants">constant</a>
operands and are evaluated at compile-time. operands and are evaluated at compile time.
</p> </p>
<p> <p>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment