]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: use consistent error messages for invalid struct literals
authorRobert Griesemer <gri@golang.org>
Wed, 5 Oct 2022 01:18:01 +0000 (18:18 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 5 Oct 2022 16:52:44 +0000 (16:52 +0000)
Fixes #51879.

Change-Id: Ic7ac892b82a0fe4ad6f95ff8ae84e6d30c52c111
Reviewed-on: https://go-review.googlesource.com/c/go/+/438855
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/types2/expr.go
src/go/types/expr.go
src/internal/types/testdata/check/expr3.go
src/internal/types/testdata/fixedbugs/issue51877.go

index 6abd9ca31103824e16d1e33a2f1c303a47be71a0..23592a86c7aa9708772d7d92cbd8096408edb0aa 100644 (file)
@@ -1385,6 +1385,9 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
                        if len(e.ElemList) == 0 {
                                break
                        }
+                       // Convention for error messages on invalid struct literals:
+                       // we mention the struct type only if it clarifies the error
+                       // (e.g., a duplicate field error doesn't need the struct type).
                        fields := utyp.fields
                        if _, ok := e.ElemList[0].(*syntax.KeyValueExpr); ok {
                                // all elements must have keys
@@ -1428,20 +1431,20 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
                                        }
                                        check.expr(x, e)
                                        if i >= len(fields) {
-                                               check.errorf(x, _InvalidStructLit, "too many values in %s{…}", base)
+                                               check.errorf(x, _InvalidStructLit, "too many values in struct literal of type %s", base)
                                                break // cannot continue
                                        }
                                        // i < len(fields)
                                        fld := fields[i]
                                        if !fld.Exported() && fld.pkg != check.pkg {
-                                               check.errorf(x, _UnexportedLitField, "implicit assignment to unexported field %s in %s literal", fld.name, typ)
+                                               check.errorf(x, _UnexportedLitField, "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
                                                continue
                                        }
                                        etyp := fld.typ
                                        check.assignment(x, etyp, "struct literal")
                                }
                                if len(e.ElemList) < len(fields) {
-                                       check.errorf(e.Rbrace, _InvalidStructLit, "too few values in %s{…}", base)
+                                       check.errorf(e.Rbrace, _InvalidStructLit, "too few values in struct literal of type %s", base)
                                        // ok to continue
                                }
                        }
index 958082a962e874f22afe6e0624ea851e84491fd1..dbc446f47bb2f709e47f6ca9f25667632be3dc83 100644 (file)
@@ -1364,6 +1364,9 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                        if len(e.Elts) == 0 {
                                break
                        }
+                       // Convention for error messages on invalid struct literals:
+                       // we mention the struct type only if it clarifies the error
+                       // (e.g., a duplicate field error doesn't need the struct type).
                        fields := utyp.fields
                        if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
                                // all elements must have keys
@@ -1407,7 +1410,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                                        }
                                        check.expr(x, e)
                                        if i >= len(fields) {
-                                               check.errorf(x, _InvalidStructLit, "too many values in %s{…}", base)
+                                               check.errorf(x, _InvalidStructLit, "too many values in struct literal of type %s", base)
                                                break // cannot continue
                                        }
                                        // i < len(fields)
@@ -1415,14 +1418,14 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                                        if !fld.Exported() && fld.pkg != check.pkg {
                                                check.errorf(x,
                                                        _UnexportedLitField,
-                                                       "implicit assignment to unexported field %s in %s literal", fld.name, typ)
+                                                       "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
                                                continue
                                        }
                                        etyp := fld.typ
                                        check.assignment(x, etyp, "struct literal")
                                }
                                if len(e.Elts) < len(fields) {
-                                       check.errorf(inNode(e, e.Rbrace), _InvalidStructLit, "too few values in %s{…}", base)
+                                       check.errorf(inNode(e, e.Rbrace), _InvalidStructLit, "too few values in struct literal of type %s", base)
                                        // ok to continue
                                }
                        }
index a28d119f4e00dc03888844761345b676f7bd7004..2ca39866fcc2aeb1be625167653f5c9698c23a60 100644 (file)
@@ -209,7 +209,7 @@ func struct_literals() {
        _ = time.Time{}
        _ = time.Time{sec /* ERROR "unknown field" */ : 0}
        _ = time.Time{
-               0 /* ERROR implicit assignment to unexported field wall in time.Time literal */,
+               0 /* ERROR implicit assignment to unexported field wall in struct literal */,
                0 /* ERROR implicit assignment */ ,
                nil /* ERROR implicit assignment */ ,
        }
index 06f054b257bdb73e969d65ff45278a15279635d1..c93242adcebacbd0d40248f8b6758ac835a4ae8c 100644 (file)
@@ -10,9 +10,9 @@ type S struct {
 }
 
 var (
-       _ = S{0}                    /* ERROR too few values in S{…} */
-       _ = struct{ f1, f2 int }{0} /* ERROR too few values in struct{f1 int; f2 int}{…} */
+       _ = S{0}                    /* ERROR too few values in struct literal */
+       _ = struct{ f1, f2 int }{0} /* ERROR too few values in struct literal */
 
-       _ = S{0, true, "foo" /* ERROR too many values in S{…} */}
-       _ = struct{ f1, f2 int }{0, 1, 2 /* ERROR too many values in struct{f1 int; f2 int}{…} */}
+       _ = S{0, true, "foo" /* ERROR too many values in struct literal */}
+       _ = struct{ f1, f2 int }{0, 1, 2 /* ERROR too many values in struct literal */}
 )