cmd/compile: cleanup algtype code
Add AlgKind enum type to represent AFOO values.
Add IsComparable, IsRegularMemory, IncomparableField helper methods to
codify common higher-level idioms.
Passes toolstash -cmp.
Change-Id: I54c544953997a8ccc72396b3058897edcbbea392
Reviewed-on: https://go-review.googlesource.com/21420
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go
index ae8af76..996bd6911 100644
--- a/src/cmd/compile/internal/gc/swt.go
+++ b/src/cmd/compile/internal/gc/swt.go
@@ -83,16 +83,17 @@
t = Types[TBOOL]
}
if t != nil {
- var badtype *Type
switch {
case !okforeq[t.Etype]:
Yyerror("cannot switch on %v", Nconv(n.Left, FmtLong))
- case t.Etype == TARRAY && !t.IsArray():
+ case t.IsSlice():
nilonly = "slice"
- case t.Etype == TARRAY && t.IsArray() && algtype1(t, nil) == ANOEQ:
+ case t.IsArray() && !t.IsComparable():
Yyerror("cannot switch on %v", Nconv(n.Left, FmtLong))
- case t.IsStruct() && algtype1(t, &badtype) == ANOEQ:
- Yyerror("cannot switch on %v (struct containing %v cannot be compared)", Nconv(n.Left, FmtLong), badtype)
+ case t.IsStruct():
+ if f := t.IncomparableField(); f != nil {
+ Yyerror("cannot switch on %v (struct containing %v cannot be compared)", Nconv(n.Left, FmtLong), f.Type)
+ }
case t.Etype == TFUNC:
nilonly = "func"
case t.IsMap():
@@ -139,7 +140,7 @@
}
case nilonly != "" && !isnil(n1):
Yyerror("invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
- case t.IsInterface() && !n1.Type.IsInterface() && algtype1(n1.Type, nil) == ANOEQ:
+ case t.IsInterface() && !n1.Type.IsInterface() && !n1.Type.IsComparable():
Yyerror("invalid case %v in switch (incomparable type)", Nconv(n1, FmtLong))
}