]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: point out type parameters with predeclared names in errors
authorRobert Griesemer <gri@golang.org>
Tue, 21 Feb 2023 22:42:18 +0000 (14:42 -0800)
committerGopher Robot <gobot@golang.org>
Wed, 22 Feb 2023 00:40:19 +0000 (00:40 +0000)
If a type parameter has the same name as a predeclared type, error
messages can be very confusing. In these rare cases, explicitly
point out where the type parameter is declared (types2) or that it
is a type parameter (go/types).

(We can't point out where the type parameter is declared in go/types
because we don't have access to the file set in the type writer at
the moment.)

Fixes #58611.

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

src/cmd/compile/internal/types2/typestring.go
src/go/types/typestring.go
src/internal/types/testdata/fixedbugs/issue58611.go [new file with mode: 0644]

index ecabe013e39fba9170a19e8f08212e9360c09791..2f4fb5220dca3f86fcc5b58df8cf63e2027db26a 100644 (file)
@@ -317,6 +317,13 @@ func (w *typeWriter) typ(typ Type) {
                        if w.tpSubscripts || w.ctxt != nil {
                                w.string(subscript(t.id))
                        }
+                       // If the type parameter name is the same as a predeclared object
+                       // (say int), point out where it is declared to avoid confusing
+                       // error messages. This doesn't need to be super-elegant; we just
+                       // need a clear indication that this is not a predeclared name.
+                       if w.ctxt == nil && Universe.Lookup(t.obj.name) != nil {
+                               w.string(sprintf(nil, false, " /* with %s declared at %s */", t.obj.name, t.obj.Pos()))
+                       }
                }
 
        default:
index 9683a0ad1da668cca29dbe568386119b2837b67f..9615e24157a5a62d23fcdbe6275f1f9e9e55675b 100644 (file)
@@ -318,6 +318,15 @@ func (w *typeWriter) typ(typ Type) {
                        if w.tpSubscripts || w.ctxt != nil {
                                w.string(subscript(t.id))
                        }
+                       // If the type parameter name is the same as a predeclared object
+                       // (say int), point out where it is declared to avoid confusing
+                       // error messages. This doesn't need to be super-elegant; we just
+                       // need a clear indication that this is not a predeclared name.
+                       // Note: types2 prints position information here - we can't do
+                       //       that because we don't have a token.FileSet accessible.
+                       if w.ctxt == nil && Universe.Lookup(t.obj.name) != nil {
+                               w.string("/* type parameter */")
+                       }
                }
 
        default:
diff --git a/src/internal/types/testdata/fixedbugs/issue58611.go b/src/internal/types/testdata/fixedbugs/issue58611.go
new file mode 100644 (file)
index 0000000..1ff30f7
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2023 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
+
+import (
+       "sort"
+       "strings"
+)
+
+func f[int any](x int) {
+       x = 0 /* ERRORx "cannot use 0.*(as int.*with int declared at|type parameter)" */
+}
+
+// test case from issue
+
+type Set[T comparable] map[T]struct{}
+
+func (s *Set[string]) String() string {
+       keys := make([]string, 0, len(*s))
+       for k := range *s {
+               keys = append(keys, k)
+       }
+       sort.Strings(keys /* ERRORx "cannot use keys.*with string declared at.*|type parameter" */ )
+       return strings /* ERROR "cannot use strings.Join" */ .Join(keys /* ERRORx "cannot use keys.*with string declared at.*|type parameter" */ , ",")
+}