Extracted from #63523. Compiling this program
package p
func F[T comparable](a, b T) bool {
return a < b
}
produces
foo.go:4:9: invalid operation: a < b (type parameter T is not comparable with <)
It is somewhat confusing that the error message says that "T is not comparable" when the constraint for T
is comparable
. Not a major issue, but we should use better wording here.
Comment From: cuonglm
I think we should mention about the invalid operator instead. Something like:
foo.go:4:9: invalid operation: a < b (operator < does not apply to comparable type T)
Comment From: kavinaravind
looks like the error is defined in src/cmd/compile/internal/types2/expr.go and src/go/types/expr.go
From a quick look, it seems that the phrase "is not comparable" is a common phrase for go errors, although I completely agree that the error message can be a bit confusing
Comment From: meling
I think we should mention about the invalid operator instead. Something like:
foo.go:4:9: invalid operation: a < b (operator < does not apply to comparable type T)
For the error message to be helpful, it has to make reference to cmp.Ordered
. For example:
foo.go:4:9: invalid operation: a < b (type parameter T must satisfy cmp.Ordered interface to be used with <)
foo.go:4:9: invalid operation: a < b (type parameter T must be cmp.Ordered with <)
foo.go:4:9: invalid operation: a < b (type parameter T is missing cmp.Ordered required for <)
foo.go:4:9: invalid operation: a < b (operator < with type parameter T must satisfy cmp.Ordered)
foo.go:4:9: invalid operation: a < b (operator < with type T must be cmp.Ordered)
Comment From: cuonglm
For the error message to be helpful, it has to make reference to cmp.Ordered.
There could be any kind of operators here, so not sure it's feasible (or worth) to report it.
Comment From: blackgreen100
IMO the key distinction that users need to be aware of is the one mentioned by the spec about comparable vs. ordered.
Therefore it could be enough to parametrize the comparable
bit of the error message (seen at line 580) based on the operator:
cause = check.sprintf("type parameter %s is not %s with %s", errOp.typ, op, verb)
where verb
could be "comparable" when op
is syntax.Eql, syntax.Neq:
and "orderable" if op
is syntax.Lss, syntax.Leq, syntax.Gtr, syntax.Geq
.
The term "orderable" would fit in that sentence structure but has the disadvantage of being informal (probably not even grammatical English, not sure about that). The spec use the term "ordered". So an alternative would be to allow the error messages to diverge. For example, a logic like this:
switch op {
case syntax.Eql, syntax.Neq:
cause = check.sprintf("type parameter %s is not comparable with %s", errOp.typ, op)
case syntax.Lss, syntax.Leq, syntax.Gtr, syntax.Geq:
cause = check.sprintf("type parameter %s can not be ordered with %s", errOp.typ, op)
}
Comment From: gopherbot
Change https://go.dev/cl/613756 mentions this issue: go/types, types2: better error message when type argument cannot use operator