1
0
mirror of https://github.com/golang/go synced 2024-11-22 05:34:39 -07:00

go/types, types2: report type name in comp. literal error, if possible

When reporting an error for the element type of a struct literal, use
the element type's type name rather than it's underlying/core type.

Also, combine error reporting for invalid composite literal types in
one place, at the end.

Fixes #68184.

Change-Id: I1f407d5403777948da9a0eca95aacc1389f4bd44
Reviewed-on: https://go-review.googlesource.com/c/go/+/595075
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Tim King <taking@google.com>
This commit is contained in:
Robert Griesemer 2024-06-25 15:31:06 -07:00 committed by Gopher Robot
parent 77a3c3b984
commit 0509936823
3 changed files with 68 additions and 10 deletions

View File

@ -1151,6 +1151,7 @@ func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr, hint Ty
case *syntax.CompositeLit:
var typ, base Type
var isElem bool // true if composite literal is an element of an enclosing composite literal
switch {
case e.Type != nil:
@ -1171,11 +1172,12 @@ func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr, hint Ty
case hint != nil:
// no composite literal type present - use hint (element type of enclosing type)
typ = hint
base, _ = deref(coreType(typ)) // *T implies &T{}
if base == nil {
check.errorf(e, InvalidLit, "invalid composite literal element type %s (no core type)", typ)
goto Error
base = typ
// *T implies &T{}
if b, ok := deref(coreType(base)); ok {
base = b
}
isElem = true
default:
// TODO(gri) provide better error messages depending on context
@ -1361,7 +1363,15 @@ func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr, hint Ty
}
// if utyp is invalid, an error was reported before
if isValid(utyp) {
check.errorf(e, InvalidLit, "invalid composite literal type %s", typ)
var qualifier string
if isElem {
qualifier = " element"
}
var cause string
if utyp == nil {
cause = " (no core type)"
}
check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
goto Error
}
}

View File

@ -1129,6 +1129,7 @@ func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type)
case *ast.CompositeLit:
var typ, base Type
var isElem bool // true if composite literal is an element of an enclosing composite literal
switch {
case e.Type != nil:
@ -1151,11 +1152,12 @@ func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type)
case hint != nil:
// no composite literal type present - use hint (element type of enclosing type)
typ = hint
base, _ = deref(coreType(typ)) // *T implies &T{}
if base == nil {
check.errorf(e, InvalidLit, "invalid composite literal element type %s (no core type)", typ)
goto Error
base = typ
// *T implies &T{}
if b, ok := deref(coreType(base)); ok {
base = b
}
isElem = true
default:
// TODO(gri) provide better error messages depending on context
@ -1343,7 +1345,15 @@ func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type)
}
// if utyp is invalid, an error was reported before
if isValid(utyp) {
check.errorf(e, InvalidLit, "invalid composite literal type %s", typ)
var qualifier string
if isElem {
qualifier = " element"
}
var cause string
if utyp == nil {
cause = " (no core type)"
}
check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
goto Error
}
}

View File

@ -0,0 +1,38 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
type VeryLongStruct struct {
A1 int
A2 int
A3 int
A4 int
A5 int
A6 int
A7 int
A8 int
A9 int
A10 int
A11 int
A12 int
A13 int
A14 int
A15 int
A16 int
A17 int
A18 int
A19 int
A20 int
}
func _() {
// The error messages in both these cases should print the
// struct name rather than the struct's underlying type.
var x VeryLongStruct
x.B2 /* ERROR "x.B2 undefined (type VeryLongStruct has no field or method B2)" */ = false
_ = []VeryLongStruct{{B2 /* ERROR "unknown field B2 in struct literal of type VeryLongStruct" */ : false}}
}