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:
parent
77a3c3b984
commit
0509936823
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
38
src/internal/types/testdata/fixedbugs/issue68184.go
vendored
Normal file
38
src/internal/types/testdata/fixedbugs/issue68184.go
vendored
Normal 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}}
|
||||
}
|
Loading…
Reference in New Issue
Block a user