]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: restore original assignment error messages
authorRobert Griesemer <gri@golang.org>
Thu, 25 Nov 2021 00:18:57 +0000 (16:18 -0800)
committerRobert Griesemer <gri@golang.org>
Mon, 29 Nov 2021 22:02:45 +0000 (22:02 +0000)
This is the missing portion of the port of CL 351669
from types2 to go/types, now that we have a local flag
to control for compiler error messages.

Mostly a clean port but for adjustments to error reporting
which requires error codes in go/types.

Prerequisite for port of CL 364874.

Change-Id: I5fc8c83003e4396351f42e9adb08f4ebc8a05653
Reviewed-on: https://go-review.googlesource.com/c/go/+/367195
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/go/types/assignments.go
src/go/types/expr.go

index 7e6a230b48c2e52f386b8a67ee87df1671ad03f3..8e9724e911df14d2a878016ca01589bf96a09f00 100644 (file)
@@ -7,6 +7,7 @@
 package types
 
 import (
+       "fmt"
        "go/ast"
        "go/token"
 )
@@ -237,6 +238,28 @@ func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
        return x.typ
 }
 
+func (check *Checker) assignError(rhs []ast.Expr, nvars, nvals int) {
+       measure := func(x int, unit string) string {
+               s := fmt.Sprintf("%d %s", x, unit)
+               if x != 1 {
+                       s += "s"
+               }
+               return s
+       }
+
+       vars := measure(nvars, "variable")
+       vals := measure(nvals, "value")
+       rhs0 := rhs[0]
+
+       if len(rhs) == 1 {
+               if call, _ := unparen(rhs0).(*ast.CallExpr); call != nil {
+                       check.errorf(rhs0, _WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
+                       return
+               }
+       }
+       check.errorf(rhs0, _WrongAssignCount, "assignment mismatch: %s but %s", vars, vals)
+}
+
 // If returnPos is valid, initVars is called to type-check the assignment of
 // return expressions, and returnPos is the position of the return statement.
 func (check *Checker) initVars(lhs []*Var, origRHS []ast.Expr, returnPos token.Pos) {
@@ -260,7 +283,11 @@ func (check *Checker) initVars(lhs []*Var, origRHS []ast.Expr, returnPos token.P
                        check.errorf(atPos(returnPos), _WrongResultCount, "wrong number of return values (want %d, got %d)", len(lhs), len(rhs))
                        return
                }
-               check.errorf(rhs[0], _WrongAssignCount, "cannot initialize %d variables with %d values", len(lhs), len(rhs))
+               if compilerErrorMessages {
+                       check.assignError(origRHS, len(lhs), len(rhs))
+               } else {
+                       check.errorf(rhs[0], _WrongAssignCount, "cannot initialize %d variables with %d values", len(lhs), len(rhs))
+               }
                return
        }
 
@@ -294,7 +321,11 @@ func (check *Checker) assignVars(lhs, origRHS []ast.Expr) {
                                return
                        }
                }
-               check.errorf(rhs[0], _WrongAssignCount, "cannot assign %d values to %d variables", len(rhs), len(lhs))
+               if compilerErrorMessages {
+                       check.assignError(origRHS, len(lhs), len(rhs))
+               } else {
+                       check.errorf(rhs[0], _WrongAssignCount, "cannot assign %d values to %d variables", len(rhs), len(lhs))
+               }
                return
        }
 
index c49865aec6b1933beaa6d8252cb97b05d73e4aee..dd18abaf132ca88317c111188f0957a77c0661d2 100644 (file)
@@ -1657,7 +1657,11 @@ func (check *Checker) singleValue(x *operand) {
                // tuple types are never named - no need for underlying type below
                if t, ok := x.typ.(*Tuple); ok {
                        assert(t.Len() != 1)
-                       check.errorf(x, _TooManyValues, "%d-valued %s where single value is expected", t.Len(), x)
+                       if compilerErrorMessages {
+                               check.errorf(x, _TooManyValues, "multiple-value %s in single-value context", x)
+                       } else {
+                               check.errorf(x, _TooManyValues, "%d-valued %s where single value is expected", t.Len(), x)
+                       }
                        x.mode = invalid
                }
        }