aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal
diff options
context:
space:
mode:
authorAlan Donovan <adonovan@google.com>2025-12-18 12:27:11 -0500
committerGopher Robot <gobot@golang.org>2026-01-15 15:10:27 -0800
commit532e3203492ebcac67b2f3aa2a52115f49d51997 (patch)
treeca524691be1918841d9a976c8ccd76db26c3d388 /src/cmd/compile/internal
parentbb7c0c717c8b3517210dce8f38cb2c91694af4e2 (diff)
downloadgo-532e3203492ebcac67b2f3aa2a52115f49d51997.tar.xz
go/types,cmd/compile/internal/types2: better diagnostic for type shadowing
This change causes the "x is not a type" diagnostic to describe x's actual kind, helping to reveal when shadowing is at work. (The kind description could improve other errors too.) Fixes #76877 Change-Id: Ia3484998bb384ff570c20b6792cf8461c60aa38c Reviewed-on: https://go-review.googlesource.com/c/go/+/731180 Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src/cmd/compile/internal')
-rw-r--r--src/cmd/compile/internal/types2/object.go49
-rw-r--r--src/cmd/compile/internal/types2/typexpr.go3
2 files changed, 51 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/types2/object.go b/src/cmd/compile/internal/types2/object.go
index dd2d415790..5d284ee61b 100644
--- a/src/cmd/compile/internal/types2/object.go
+++ b/src/cmd/compile/internal/types2/object.go
@@ -671,3 +671,52 @@ func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
}
buf.WriteString(f.name)
}
+
+// objectKind returns a description of the object's kind.
+func objectKind(obj Object) string {
+ switch obj := obj.(type) {
+ case *PkgName:
+ return "package name"
+ case *Const:
+ return "constant"
+ case *TypeName:
+ if obj.IsAlias() {
+ return "type alias"
+ } else if _, ok := obj.Type().(*TypeParam); ok {
+ return "type parameter"
+ } else {
+ return "defined type"
+ }
+ case *Var:
+ switch obj.Kind() {
+ case PackageVar:
+ return "package-level variable"
+ case LocalVar:
+ return "local variable"
+ case RecvVar:
+ return "receiver"
+ case ParamVar:
+ return "parameter"
+ case ResultVar:
+ return "result variable"
+ case FieldVar:
+ return "struct field"
+ }
+ case *Func:
+ if obj.Signature().Recv() != nil {
+ return "method"
+ } else {
+ return "function"
+ }
+ case *Label:
+ return "label"
+ case *Builtin:
+ return "built-in function"
+ case *Nil:
+ return "untyped nil"
+ }
+ if debug {
+ panic(fmt.Sprintf("unknown symbol (%T)", obj))
+ }
+ return "unknown symbol"
+}
diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go
index a79b54eacc..7d5932eec1 100644
--- a/src/cmd/compile/internal/types2/typexpr.go
+++ b/src/cmd/compile/internal/types2/typexpr.go
@@ -50,7 +50,8 @@ func (check *Checker) ident(x *operand, e *syntax.Name, wantType bool) {
// (see go.dev/issue/65344).
_, gotType := obj.(*TypeName)
if !gotType && wantType {
- check.errorf(e, NotAType, "%s is not a type", obj.Name())
+ check.errorf(e, NotAType, "%s (%s) is not a type", obj.Name(), objectKind(obj))
+
// avoid "declared but not used" errors
// (don't use Checker.use - we don't want to evaluate too much)
if v, _ := obj.(*Var); v != nil && v.pkg == check.pkg /* see Checker.use1 */ {