]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: don't drop type in n:1 var decl if one is given
authorRobert Griesemer <gri@golang.org>
Sat, 21 May 2016 00:26:24 +0000 (17:26 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 23 May 2016 18:19:40 +0000 (18:19 +0000)
In n:1 variable declarations (multiple lhs variables with single
multi-valued initialization expression) where also a variable
type is provided, make sure that that type is assigned to all
variables on the lhs before the init expression assignment is
checked. Otherwise, (some) variables are assumed to take the type
of the corresponding value of the multi-valued init expression.

Fixes #15755.

Change-Id: I969cb5a95c85e28dbb38abd7fa7df16ff5554c03
Reviewed-on: https://go-review.googlesource.com/23313
Reviewed-by: Alan Donovan <adonovan@google.com>
src/go/types/decl.go
src/go/types/testdata/issues.src

index f064f6856f24f7dc1b52d0393bd575e0f11de2be..1ecfb35f60c3ee2357ae928adff25cca1e346190 100644 (file)
@@ -141,6 +141,14 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
        // determine type, if any
        if typ != nil {
                obj.typ = check.typ(typ)
+               // We cannot spread the type to all lhs variables if there
+               // are more than one since that would mark them as checked
+               // (see Checker.objDecl) and the assignment of init exprs,
+               // if any, would not be checked.
+               //
+               // TODO(gri) If we have no init expr, we should distribute
+               // a given type otherwise we need to re-evalate the type
+               // expr for each lhs variable, leading to duplicate work.
        }
 
        // check initialization
@@ -173,6 +181,17 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
                        panic("inconsistent lhs")
                }
        }
+
+       // We have multiple variables on the lhs and one init expr.
+       // Make sure all variables have been given the same type if
+       // one was specified, otherwise they assume the type of the
+       // init expression values (was issue #15755).
+       if typ != nil {
+               for _, lhs := range lhs {
+                       lhs.typ = obj.typ
+               }
+       }
+
        check.initVars(lhs, []ast.Expr{init}, token.NoPos)
 }
 
index 4fe0c629386776b583188ef35bff3f7d9ea7ebf2..6579aa3b117b65450f4cb4ef9b2cdf6acaed5738 100644 (file)
@@ -170,3 +170,19 @@ func issue14229() {
                _ = b % a
        )
 }
+
+// Check that in a n:1 variable declaration with type and initialization
+// expression the type is distributed to all variables of the lhs before
+// the initialization expression assignment is checked.
+func issue15755() {
+       // from issue
+       var i interface{}
+       type b bool
+       var x, y b = i.(b)
+       _ = x == y
+
+       // related: we should see an error since the result of f1 is ([]int, int)
+       var u, v []int = f1 /* ERROR cannot use f1 */ ()
+       _ = u
+       _ = v
+}