]> Cypherpunks repositories - gostls13.git/commitdiff
spec: document existing expression switch restrictions
authorRobert Griesemer <gri@golang.org>
Mon, 27 Jul 2015 20:30:16 +0000 (13:30 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 30 Jul 2015 23:11:20 +0000 (23:11 +0000)
The spec didn't specify several aspects of expression switches:

- The switch expression is evaluated exactly once.

- Switch expressions evaluating to an untyped value are converted
  to the respective default type before use.

- An (untyped) nil value is not permitted as expression switch
  value. (We could permit it relatively easily, but gc doesn't,
  and disallowing it is in symmetry with the rules for var decls
  without explicit type and untyped initializer expressions.)

- The comparison x == t between each case expression x and
  switch expression value t must be valid.

- (Some) duplicate constant case expressions are not permitted.

This change also clarifies the following issues:

 4524: mult. equal int const switch case values should be illegal
                                         -> spec issue fixed
 6398: switch w/ no value uses bool rather than untyped bool
                                         -> spec issue fixed
11578: allows duplicate switch cases     -> go/types bug
11667: int overflow in switch expression -> go/types bug
11668: use of untyped nil in switch      -> not a gc bug

Fixes #4524.
Fixes #6398.
Fixes #11668.

Change-Id: Iae4ab3e714575a5d11c92c9b8fbf027aa706b370
Reviewed-on: https://go-review.googlesource.com/12711
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
doc/go_spec.html

index 95406a16876bc9ba430ea9a847b867be01ee0ff3..14fa44c675955428df57f7ca8c9e8471f5a5f469 100644 (file)
@@ -1,6 +1,6 @@
 <!--{
        "Title": "The Go Programming Language Specification",
-       "Subtitle": "Version of July 23, 2015",
+       "Subtitle": "Version of July 30, 2015",
        "Path": "/ref/spec"
 }-->
 
@@ -662,7 +662,7 @@ acts like a variable.
 </p>
 
 <p>
-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 given in its declaration, the type provided in the
 <code>new</code> call or composite literal, or the type of
 an element of a structured variable.
@@ -672,8 +672,8 @@ which is the concrete type of the value assigned to the variable at run time
 which has no type).
 The dynamic type may vary during execution but values stored in interface
 variables are always <a href="#Assignability">assignable</a>
-to the static type of the variable.    
-</p>   
+to the static type of the variable.
+</p>
 
 <pre>
 var x interface{}  // x is nil and has static type interface{}
@@ -4550,6 +4550,7 @@ In an expression switch, the cases contain expressions that are compared
 against the value of the switch expression.
 In a type switch, the cases contain types that are compared against the
 type of a specially annotated switch expression.
+The switch expression is evaluated exactly once in a switch statement.
 </p>
 
 <h4 id="Expression_switches">Expression switches</h4>
@@ -4576,6 +4577,27 @@ ExprCaseClause = ExprSwitchCase ":" StatementList .
 ExprSwitchCase = "case" ExpressionList | "default" .
 </pre>
 
+<p>
+If the switch expression evaluates to an untyped constant, it is first
+<a href="#Conversions">converted</a> to its <a href="#Constants">default type</a>;
+if it is an untyped boolean value, it is first converted to type <code>bool</code>.
+The predeclared untyped value <code>nil</code> cannot be used as a switch expression.
+</p>
+
+<p>
+If a case expression is untyped, it is first <a href="#Conversions">converted</a>
+to the type of the switch expression.
+For each (possibly converted) case expression <code>x</code> and the value <code>t</code>
+of the switch expression, <code>x == t</code> must be a valid <a href="#Comparison_operators">comparison</a>.
+</p>
+
+<p>
+In other words, the switch expression is treated as if it were used to declare and
+initialize a temporary variable <code>t</code> without explicit type; it is that
+value of <code>t</code> against which each case expression <code>x</code> is tested
+for equality.
+</p>
+
 <p>
 In a case or default clause, the last non-empty statement
 may be a (possibly <a href="#Labeled_statements">labeled</a>)
@@ -4588,7 +4610,7 @@ but the last clause of an expression switch.
 </p>
 
 <p>
-The expression may be preceded by a simple statement, which
+The switch expression may be preceded by a simple statement, which
 executes before the expression is evaluated.
 </p>
 
@@ -4611,6 +4633,13 @@ case x == 4: f3()
 }
 </pre>
 
+<p>
+Implementation restriction: A compiler may disallow multiple case
+expressions evaluating to the same constant.
+For instance, the current compilers disallow duplicate integer,
+floating point, or string constants in case expressions.
+</p>
+
 <h4 id="Type_switches">Type switches</h4>
 
 <p>