aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types/type.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2021-06-09 19:30:16 -0700
committerKeith Randall <khr@golang.org>2021-07-21 21:04:15 +0000
commita7a17f0ca86d252dc1ef20b5852c352ade5f8610 (patch)
treefdc726eb6a687dfb988e927fdef467cd393bfaa1 /src/cmd/compile/internal/types/type.go
parent897970688b326f7baa8ad8e3330fb552d94b0014 (diff)
downloadgo-a7a17f0ca86d252dc1ef20b5852c352ade5f8610.tar.gz
go-a7a17f0ca86d252dc1ef20b5852c352ade5f8610.zip
[dev.typeparams] cmd/compile: introduce named gcshape types
Still 1-1 with real types, but now with their own names! Shape types are implicitly convertible to (and convertible from) the types they represent. Change-Id: I0133a8d8fbeb369380574b075a32b3c987e314d5 Reviewed-on: https://go-review.googlesource.com/c/go/+/335170 Run-TryBot: Keith Randall <khr@golang.org> Trust: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Reviewed-by: Dan Scales <danscales@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types/type.go')
-rw-r--r--src/cmd/compile/internal/types/type.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go
index 28312111ad..e6ae0e7bc1 100644
--- a/src/cmd/compile/internal/types/type.go
+++ b/src/cmd/compile/internal/types/type.go
@@ -210,6 +210,7 @@ const (
typeDeferwidth // width computation has been deferred and type is on deferredTypeStack
typeRecur
typeHasTParam // there is a typeparam somewhere in the type (generic function or type)
+ typeIsShape // represents a set of closely related types, for generics
)
func (t *Type) NotInHeap() bool { return t.flags&typeNotInHeap != 0 }
@@ -218,12 +219,14 @@ func (t *Type) Noalg() bool { return t.flags&typeNoalg != 0 }
func (t *Type) Deferwidth() bool { return t.flags&typeDeferwidth != 0 }
func (t *Type) Recur() bool { return t.flags&typeRecur != 0 }
func (t *Type) HasTParam() bool { return t.flags&typeHasTParam != 0 }
+func (t *Type) IsShape() bool { return t.flags&typeIsShape != 0 }
func (t *Type) SetNotInHeap(b bool) { t.flags.set(typeNotInHeap, b) }
func (t *Type) SetBroke(b bool) { t.flags.set(typeBroke, b) }
func (t *Type) SetNoalg(b bool) { t.flags.set(typeNoalg, b) }
func (t *Type) SetDeferwidth(b bool) { t.flags.set(typeDeferwidth, b) }
func (t *Type) SetRecur(b bool) { t.flags.set(typeRecur, b) }
+func (t *Type) SetIsShape(b bool) { t.flags.set(typeIsShape, b) }
// Generic types should never have alg functions.
func (t *Type) SetHasTParam(b bool) { t.flags.set(typeHasTParam, b); t.flags.set(typeNoalg, b) }
@@ -2147,3 +2150,46 @@ var (
)
var SimType [NTYPE]Kind
+
+// Reports whether t has a shape type anywere.
+func (t *Type) HasShape() bool {
+ return t.HasShape1(map[*Type]bool{})
+}
+func (t *Type) HasShape1(visited map[*Type]bool) bool {
+ if t.IsShape() {
+ return true
+ }
+ if visited[t] {
+ return false
+ }
+ visited[t] = true
+ if t.Sym() != nil {
+ for _, u := range t.RParams() {
+ if u.HasShape1(visited) {
+ return true
+ }
+ }
+ }
+ switch t.Kind() {
+ case TPTR, TARRAY, TSLICE, TCHAN:
+ return t.Elem().HasShape1(visited)
+ case TMAP:
+ return t.Elem().HasShape1(visited) || t.Key().HasShape1(visited)
+ case TSTRUCT:
+ for _, f := range t.FieldSlice() {
+ if f.Type.HasShape1(visited) {
+ return true
+ }
+ }
+ case TFUNC:
+ for _, a := range RecvsParamsResults {
+ for _, f := range a(t).FieldSlice() {
+ if f.Type.HasShape1(visited) {
+ return true
+ }
+ }
+ }
+ // TODO: TINTER - check methods?
+ }
+ return false
+}