}
cause = check.sprintf("type parameter %s cannot use operator %s", errOp.typ, op)
} else {
- cause = check.sprintf("operator %s not defined on %s", op, check.kindString(errOp.typ)) // catch-all
+ // catch-all: neither x nor y is a type parameter
+ what := compositeKind(errOp.typ)
+ if what == "" {
+ what = check.sprintf("%s", errOp.typ)
+ }
+ cause = check.sprintf("operator %s not defined on %s", op, what)
}
}
if switchCase {
func (check *Checker) incomparableCause(typ Type) string {
switch under(typ).(type) {
case *Slice, *Signature, *Map:
- return check.kindString(typ) + " can only be compared to nil"
+ return compositeKind(typ) + " can only be compared to nil"
}
// see if we can extract a more specific error
var cause string
return cause
}
-// kindString returns the type kind as a string.
-func (check *Checker) kindString(typ Type) string {
- switch under(typ).(type) {
- case *Array:
- return "array"
- case *Slice:
- return "slice"
- case *Struct:
- return "struct"
- case *Pointer:
- return "pointer"
- case *Signature:
- return "func"
- case *Interface:
- if isTypeParam(typ) {
- return check.sprintf("type parameter %s", typ)
- }
- return "interface"
- case *Map:
- return "map"
- case *Chan:
- return "chan"
- default:
- return check.sprintf("%s", typ) // catch-all
- }
-}
-
// If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
// TODO(gri) This function seems overly complex. Revisit.
return buf.String()
}
+// compositeKind returns the kind of the given composite type
+// ("array", "slice", etc.) or the empty string if typ is not
+// composite but a basic type.
+func compositeKind(typ Type) string {
+ switch under(typ).(type) {
+ case *Basic:
+ return ""
+ case *Array:
+ return "array"
+ case *Slice:
+ return "slice"
+ case *Struct:
+ return "struct"
+ case *Pointer:
+ return "pointer"
+ case *Signature:
+ return "func"
+ case *Interface:
+ return "interface"
+ case *Map:
+ return "map"
+ case *Chan:
+ return "chan"
+ case *Tuple:
+ return "tuple"
+ case *Union:
+ return "union"
+ default:
+ panic("unreachable")
+ }
+}
+
func (x *operand) String() string {
return operandString(x, nil)
}
}
cause = check.sprintf("type parameter %s cannot use operator %s", errOp.typ, op)
} else {
- cause = check.sprintf("operator %s not defined on %s", op, check.kindString(errOp.typ)) // catch-all
+ // catch-all neither x nor y is a type parameter
+ what := compositeKind(errOp.typ)
+ if what == "" {
+ what = check.sprintf("%s", errOp.typ)
+ }
+ cause = check.sprintf("operator %s not defined on %s", op, what)
}
}
if switchCase {
func (check *Checker) incomparableCause(typ Type) string {
switch under(typ).(type) {
case *Slice, *Signature, *Map:
- return check.kindString(typ) + " can only be compared to nil"
+ return compositeKind(typ) + " can only be compared to nil"
}
// see if we can extract a more specific error
var cause string
return cause
}
-// kindString returns the type kind as a string.
-func (check *Checker) kindString(typ Type) string {
- switch under(typ).(type) {
- case *Array:
- return "array"
- case *Slice:
- return "slice"
- case *Struct:
- return "struct"
- case *Pointer:
- return "pointer"
- case *Signature:
- return "func"
- case *Interface:
- if isTypeParam(typ) {
- return check.sprintf("type parameter %s", typ)
- }
- return "interface"
- case *Map:
- return "map"
- case *Chan:
- return "chan"
- default:
- return check.sprintf("%s", typ) // catch-all
- }
-}
-
// If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
// TODO(gri) This function seems overly complex. Revisit.
return buf.String()
}
+// compositeKind returns the kind of the given composite type
+// ("array", "slice", etc.) or the empty string if typ is not
+// composite but a basic type.
+func compositeKind(typ Type) string {
+ switch under(typ).(type) {
+ case *Basic:
+ return ""
+ case *Array:
+ return "array"
+ case *Slice:
+ return "slice"
+ case *Struct:
+ return "struct"
+ case *Pointer:
+ return "pointer"
+ case *Signature:
+ return "func"
+ case *Interface:
+ return "interface"
+ case *Map:
+ return "map"
+ case *Chan:
+ return "chan"
+ case *Tuple:
+ return "tuple"
+ case *Union:
+ return "union"
+ default:
+ panic("unreachable")
+ }
+}
+
func (x *operand) String() string {
return operandString(x, nil)
}