aboutsummaryrefslogtreecommitdiff
path: root/src/go/types/predicates.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2022-01-31 21:25:14 -0800
committerRobert Griesemer <gri@golang.org>2022-02-04 23:42:25 +0000
commite052044d6b25a76603cafbfb1099cf4196528556 (patch)
treef66a228ec75c6821ce3b68de5d59556fa2147efe /src/go/types/predicates.go
parentf9763a648bbe4468118b95e147bc5e81268d0341 (diff)
downloadgo-e052044d6b25a76603cafbfb1099cf4196528556.tar.gz
go-e052044d6b25a76603cafbfb1099cf4196528556.zip
go/types, types2: better error messages for comparisons
Refactor Checker.comparison such that its logic is easier to reason about and so that special cases can be handled more directly. Use the appropriate operand (of 1st or 2nd operand) for error reporting (position and type), rather than always using the first operand. Use an extra parameter to indicate a switch case comparison; in this case the error is always reported at the position of the first operand. (The error messages are not yet adjusted for switches; see next CL.) Introduce a new kindString function which is used to print simplified types in error messages (related to comparisons only): instead of printing the details of a struct type, we just print "struct" where the details are not relevant. This matches the 1.17 compiler behavior. Added a "reportf" parameter to the internal comparable function so we can report an error cause in addition to the boolean result. Rather than passing a *string for cause, we pass a function to record the cause so that we can use the *Checker context for printing (needed for proper type qualification). This mechanism reports the same details now as the 1.17 compiler. Adjusted various tests as needed added new test files. Fixes #50918. Change-Id: I1f0e7af22f09db4d31679c667c71a9038a8dc9d2 Reviewed-on: https://go-review.googlesource.com/c/go/+/381964 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/go/types/predicates.go')
-rw-r--r--src/go/types/predicates.go18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/go/types/predicates.go b/src/go/types/predicates.go
index 9ae6cd51b7..23dcd7274d 100644
--- a/src/go/types/predicates.go
+++ b/src/go/types/predicates.go
@@ -104,10 +104,11 @@ func isGeneric(t Type) bool {
// Comparable reports whether values of type T are comparable.
func Comparable(T Type) bool {
- return comparable(T, nil)
+ return comparable(T, nil, nil)
}
-func comparable(T Type, seen map[Type]bool) bool {
+// If reportf != nil, it may be used to report why T is not comparable.
+func comparable(T Type, seen map[Type]bool, reportf func(string, ...interface{})) bool {
if seen[T] {
return true
}
@@ -125,13 +126,22 @@ func comparable(T Type, seen map[Type]bool) bool {
return true
case *Struct:
for _, f := range t.fields {
- if !comparable(f.typ, seen) {
+ if !comparable(f.typ, seen, nil) {
+ if reportf != nil {
+ reportf("struct containing %s cannot be compared", f.typ)
+ }
return false
}
}
return true
case *Array:
- return comparable(t.elem, seen)
+ if !comparable(t.elem, seen, nil) {
+ if reportf != nil {
+ reportf("%s cannot be compared", t)
+ }
+ return false
+ }
+ return true
case *Interface:
return !isTypeParam(T) || t.typeSet().IsComparable(seen)
}