Commit 30fc940c authored by Robert Griesemer's avatar Robert Griesemer

go/types: don't drop type in n:1 var decl if one is given

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/23313Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 65adb6ab
...@@ -141,6 +141,14 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { ...@@ -141,6 +141,14 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
// determine type, if any // determine type, if any
if typ != nil { if typ != nil {
obj.typ = check.typ(typ) 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 // check initialization
...@@ -173,6 +181,17 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { ...@@ -173,6 +181,17 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
panic("inconsistent lhs") 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) check.initVars(lhs, []ast.Expr{init}, token.NoPos)
} }
......
...@@ -170,3 +170,19 @@ func issue14229() { ...@@ -170,3 +170,19 @@ func issue14229() {
_ = b % a _ = 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
}
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