diff options
author | Keith Randall <khr@golang.org> | 2021-06-09 19:30:16 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2021-07-21 21:04:15 +0000 |
commit | a7a17f0ca86d252dc1ef20b5852c352ade5f8610 (patch) | |
tree | fdc726eb6a687dfb988e927fdef467cd393bfaa1 /src/cmd/compile/internal/types/type.go | |
parent | 897970688b326f7baa8ad8e3330fb552d94b0014 (diff) | |
download | go-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.go | 46 |
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 +} |