mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/types: replace Type.Val with Type.Elem
This reduces the API surface of Type slightly (for #25056), but also makes it more consistent with the reflect and go/types APIs. Passes toolstash-check. Change-Id: Ief9a8eb461ae6e88895f347e2a1b7b8a62423222 Reviewed-on: https://go-review.googlesource.com/109138 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
e10ee798c4
commit
2083b5d673
12 changed files with 54 additions and 63 deletions
|
|
@ -286,7 +286,7 @@ func dowidth(t *types.Type) {
|
||||||
|
|
||||||
case TMAP: // implemented as pointer
|
case TMAP: // implemented as pointer
|
||||||
w = int64(Widthptr)
|
w = int64(Widthptr)
|
||||||
checkwidth(t.Val())
|
checkwidth(t.Elem())
|
||||||
checkwidth(t.Key())
|
checkwidth(t.Key())
|
||||||
|
|
||||||
case TFORW: // should have been filled in
|
case TFORW: // should have been filled in
|
||||||
|
|
|
||||||
|
|
@ -476,12 +476,9 @@ func (p *exporter) markType(t *types.Type) {
|
||||||
// perfect. Worst case, we might miss opportunities to inline
|
// perfect. Worst case, we might miss opportunities to inline
|
||||||
// some function calls in downstream packages.
|
// some function calls in downstream packages.
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
case TPTR32, TPTR64, TARRAY, TSLICE, TCHAN:
|
case TPTR32, TPTR64, TARRAY, TSLICE, TCHAN, TMAP:
|
||||||
p.markType(t.Elem())
|
p.markType(t.Elem())
|
||||||
|
|
||||||
case TMAP:
|
|
||||||
p.markType(t.Val())
|
|
||||||
|
|
||||||
case TSTRUCT:
|
case TSTRUCT:
|
||||||
for _, f := range t.FieldSlice() {
|
for _, f := range t.FieldSlice() {
|
||||||
if types.IsExported(f.Sym.Name) || f.Embedded != 0 {
|
if types.IsExported(f.Sym.Name) || f.Embedded != 0 {
|
||||||
|
|
@ -798,7 +795,7 @@ func (p *exporter) typ(t *types.Type) {
|
||||||
case TMAP:
|
case TMAP:
|
||||||
p.tag(mapTag)
|
p.tag(mapTag)
|
||||||
p.typ(t.Key())
|
p.typ(t.Key())
|
||||||
p.typ(t.Val())
|
p.typ(t.Elem())
|
||||||
|
|
||||||
case TCHAN:
|
case TCHAN:
|
||||||
p.tag(chanTag)
|
p.tag(chanTag)
|
||||||
|
|
|
||||||
|
|
@ -587,7 +587,7 @@ func (p *importer) typ() *types.Type {
|
||||||
t = p.newtyp(TMAP)
|
t = p.newtyp(TMAP)
|
||||||
mt := t.MapType()
|
mt := t.MapType()
|
||||||
mt.Key = p.typ()
|
mt.Key = p.typ()
|
||||||
mt.Val = p.typ()
|
mt.Elem = p.typ()
|
||||||
|
|
||||||
case chanTag:
|
case chanTag:
|
||||||
t = p.newtyp(TCHAN)
|
t = p.newtyp(TCHAN)
|
||||||
|
|
|
||||||
|
|
@ -739,7 +739,7 @@ func typefmt(t *types.Type, flag FmtFlag, mode fmtMode, depth int) string {
|
||||||
return "chan " + tmodeString(t.Elem(), mode, depth)
|
return "chan " + tmodeString(t.Elem(), mode, depth)
|
||||||
|
|
||||||
case TMAP:
|
case TMAP:
|
||||||
return "map[" + tmodeString(t.Key(), mode, depth) + "]" + tmodeString(t.Val(), mode, depth)
|
return "map[" + tmodeString(t.Key(), mode, depth) + "]" + tmodeString(t.Elem(), mode, depth)
|
||||||
|
|
||||||
case TINTER:
|
case TINTER:
|
||||||
if t.IsEmptyInterface() {
|
if t.IsEmptyInterface() {
|
||||||
|
|
@ -803,19 +803,18 @@ func typefmt(t *types.Type, flag FmtFlag, mode fmtMode, depth int) string {
|
||||||
mt := m.MapType()
|
mt := m.MapType()
|
||||||
// Format the bucket struct for map[x]y as map.bucket[x]y.
|
// Format the bucket struct for map[x]y as map.bucket[x]y.
|
||||||
// This avoids a recursive print that generates very long names.
|
// This avoids a recursive print that generates very long names.
|
||||||
if mt.Bucket == t {
|
var subtype string
|
||||||
return "map.bucket[" + tmodeString(m.Key(), mode, depth) + "]" + tmodeString(m.Val(), mode, depth)
|
switch t {
|
||||||
|
case mt.Bucket:
|
||||||
|
subtype = "bucket"
|
||||||
|
case mt.Hmap:
|
||||||
|
subtype = "hdr"
|
||||||
|
case mt.Hiter:
|
||||||
|
subtype = "iter"
|
||||||
|
default:
|
||||||
|
Fatalf("unknown internal map type")
|
||||||
}
|
}
|
||||||
|
return fmt.Sprintf("map.%s[%s]%s", subtype, tmodeString(m.Key(), mode, depth), tmodeString(m.Elem(), mode, depth))
|
||||||
if mt.Hmap == t {
|
|
||||||
return "map.hdr[" + tmodeString(m.Key(), mode, depth) + "]" + tmodeString(m.Val(), mode, depth)
|
|
||||||
}
|
|
||||||
|
|
||||||
if mt.Hiter == t {
|
|
||||||
return "map.iter[" + tmodeString(m.Key(), mode, depth) + "]" + tmodeString(m.Val(), mode, depth)
|
|
||||||
}
|
|
||||||
|
|
||||||
Fatalf("unknown internal map type")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := make([]byte, 0, 64)
|
buf := make([]byte, 0, 64)
|
||||||
|
|
|
||||||
|
|
@ -638,7 +638,7 @@ func (w *exportWriter) doTyp(t *types.Type) {
|
||||||
case TMAP:
|
case TMAP:
|
||||||
w.startType(mapType)
|
w.startType(mapType)
|
||||||
w.typ(t.Key())
|
w.typ(t.Key())
|
||||||
w.typ(t.Val())
|
w.typ(t.Elem())
|
||||||
|
|
||||||
case TFUNC:
|
case TFUNC:
|
||||||
w.startType(signatureType)
|
w.startType(signatureType)
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ func typecheckrangeExpr(n *Node) {
|
||||||
|
|
||||||
case TMAP:
|
case TMAP:
|
||||||
t1 = t.Key()
|
t1 = t.Key()
|
||||||
t2 = t.Val()
|
t2 = t.Elem()
|
||||||
|
|
||||||
case TCHAN:
|
case TCHAN:
|
||||||
if !t.ChanDir().CanRecv() {
|
if !t.ChanDir().CanRecv() {
|
||||||
|
|
@ -297,7 +297,7 @@ func walkrange(n *Node) *Node {
|
||||||
|
|
||||||
fn := syslook("mapiterinit")
|
fn := syslook("mapiterinit")
|
||||||
|
|
||||||
fn = substArgTypes(fn, t.Key(), t.Val(), th)
|
fn = substArgTypes(fn, t.Key(), t.Elem(), th)
|
||||||
init = append(init, mkcall1(fn, nil, nil, typename(t), ha, nod(OADDR, hit, nil)))
|
init = append(init, mkcall1(fn, nil, nil, typename(t), ha, nod(OADDR, hit, nil)))
|
||||||
n.Left = nod(ONE, nodSym(ODOT, hit, keysym), nodnil())
|
n.Left = nod(ONE, nodSym(ODOT, hit, keysym), nodnil())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ func bmap(t *types.Type) *types.Type {
|
||||||
|
|
||||||
bucket := types.New(TSTRUCT)
|
bucket := types.New(TSTRUCT)
|
||||||
keytype := t.Key()
|
keytype := t.Key()
|
||||||
valtype := t.Val()
|
valtype := t.Elem()
|
||||||
dowidth(keytype)
|
dowidth(keytype)
|
||||||
dowidth(valtype)
|
dowidth(valtype)
|
||||||
if keytype.Width > MAXKEYSIZE {
|
if keytype.Width > MAXKEYSIZE {
|
||||||
|
|
@ -172,7 +172,7 @@ func bmap(t *types.Type) *types.Type {
|
||||||
if t.Key().Width > MAXKEYSIZE && !keytype.IsPtr() {
|
if t.Key().Width > MAXKEYSIZE && !keytype.IsPtr() {
|
||||||
Fatalf("key indirect incorrect for %v", t)
|
Fatalf("key indirect incorrect for %v", t)
|
||||||
}
|
}
|
||||||
if t.Val().Width > MAXVALSIZE && !valtype.IsPtr() {
|
if t.Elem().Width > MAXVALSIZE && !valtype.IsPtr() {
|
||||||
Fatalf("value indirect incorrect for %v", t)
|
Fatalf("value indirect incorrect for %v", t)
|
||||||
}
|
}
|
||||||
if keytype.Width%int64(keytype.Align) != 0 {
|
if keytype.Width%int64(keytype.Align) != 0 {
|
||||||
|
|
@ -286,8 +286,8 @@ func hiter(t *types.Type) *types.Type {
|
||||||
// }
|
// }
|
||||||
// must match ../../../../runtime/map.go:hiter.
|
// must match ../../../../runtime/map.go:hiter.
|
||||||
fields := []*types.Field{
|
fields := []*types.Field{
|
||||||
makefield("key", types.NewPtr(t.Key())), // Used in range.go for TMAP.
|
makefield("key", types.NewPtr(t.Key())), // Used in range.go for TMAP.
|
||||||
makefield("val", types.NewPtr(t.Val())), // Used in range.go for TMAP.
|
makefield("val", types.NewPtr(t.Elem())), // Used in range.go for TMAP.
|
||||||
makefield("t", types.Types[TUNSAFEPTR]),
|
makefield("t", types.Types[TUNSAFEPTR]),
|
||||||
makefield("h", types.NewPtr(hmap)),
|
makefield("h", types.NewPtr(hmap)),
|
||||||
makefield("buckets", types.NewPtr(bmap)),
|
makefield("buckets", types.NewPtr(bmap)),
|
||||||
|
|
@ -1245,7 +1245,7 @@ func dtypesym(t *types.Type) *obj.LSym {
|
||||||
// ../../../../runtime/type.go:/mapType
|
// ../../../../runtime/type.go:/mapType
|
||||||
case TMAP:
|
case TMAP:
|
||||||
s1 := dtypesym(t.Key())
|
s1 := dtypesym(t.Key())
|
||||||
s2 := dtypesym(t.Val())
|
s2 := dtypesym(t.Elem())
|
||||||
s3 := dtypesym(bmap(t))
|
s3 := dtypesym(bmap(t))
|
||||||
s4 := dtypesym(hmap(t))
|
s4 := dtypesym(hmap(t))
|
||||||
ot = dcommontype(lsym, t)
|
ot = dcommontype(lsym, t)
|
||||||
|
|
@ -1261,11 +1261,11 @@ func dtypesym(t *types.Type) *obj.LSym {
|
||||||
ot = duint8(lsym, ot, 0) // not indirect
|
ot = duint8(lsym, ot, 0) // not indirect
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Val().Width > MAXVALSIZE {
|
if t.Elem().Width > MAXVALSIZE {
|
||||||
ot = duint8(lsym, ot, uint8(Widthptr))
|
ot = duint8(lsym, ot, uint8(Widthptr))
|
||||||
ot = duint8(lsym, ot, 1) // indirect
|
ot = duint8(lsym, ot, 1) // indirect
|
||||||
} else {
|
} else {
|
||||||
ot = duint8(lsym, ot, uint8(t.Val().Width))
|
ot = duint8(lsym, ot, uint8(t.Elem().Width))
|
||||||
ot = duint8(lsym, ot, 0) // not indirect
|
ot = duint8(lsym, ot, 0) // not indirect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -947,7 +947,7 @@ func maplit(n *Node, m *Node, init *Nodes) {
|
||||||
|
|
||||||
// build types [count]Tindex and [count]Tvalue
|
// build types [count]Tindex and [count]Tvalue
|
||||||
tk := types.NewArray(n.Type.Key(), int64(len(stat)))
|
tk := types.NewArray(n.Type.Key(), int64(len(stat)))
|
||||||
tv := types.NewArray(n.Type.Val(), int64(len(stat)))
|
tv := types.NewArray(n.Type.Elem(), int64(len(stat)))
|
||||||
|
|
||||||
// TODO(josharian): suppress alg generation for these types?
|
// TODO(josharian): suppress alg generation for these types?
|
||||||
dowidth(tk)
|
dowidth(tk)
|
||||||
|
|
@ -1012,7 +1012,7 @@ func addMapEntries(m *Node, dyn []*Node, init *Nodes) {
|
||||||
// Use temporaries so that mapassign1 can have addressable key, val.
|
// Use temporaries so that mapassign1 can have addressable key, val.
|
||||||
// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
|
// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
|
||||||
key := temp(m.Type.Key())
|
key := temp(m.Type.Key())
|
||||||
val := temp(m.Type.Val())
|
val := temp(m.Type.Elem())
|
||||||
|
|
||||||
for _, r := range dyn {
|
for _, r := range dyn {
|
||||||
index, value := r.Left, r.Right
|
index, value := r.Left, r.Right
|
||||||
|
|
|
||||||
|
|
@ -612,7 +612,6 @@ func eqtype1(t1, t2 *types.Type, cmpTags bool, assumedEqual map[typePair]struct{
|
||||||
if !eqtype1(t1.Key(), t2.Key(), cmpTags, assumedEqual) {
|
if !eqtype1(t1.Key(), t2.Key(), cmpTags, assumedEqual) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return eqtype1(t1.Val(), t2.Val(), cmpTags, assumedEqual)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return eqtype1(t1.Elem(), t2.Elem(), cmpTags, assumedEqual)
|
return eqtype1(t1.Elem(), t2.Elem(), cmpTags, assumedEqual)
|
||||||
|
|
|
||||||
|
|
@ -1019,7 +1019,7 @@ func typecheck1(n *Node, top int) *Node {
|
||||||
if n.Right.Type != nil {
|
if n.Right.Type != nil {
|
||||||
n.Right = assignconv(n.Right, t.Key(), "map index")
|
n.Right = assignconv(n.Right, t.Key(), "map index")
|
||||||
}
|
}
|
||||||
n.Type = t.Val()
|
n.Type = t.Elem()
|
||||||
n.Op = OINDEXMAP
|
n.Op = OINDEXMAP
|
||||||
n.ResetAux()
|
n.ResetAux()
|
||||||
}
|
}
|
||||||
|
|
@ -3012,10 +3012,10 @@ func typecheckcomplit(n *Node) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
r = l.Right
|
r = l.Right
|
||||||
pushtype(r, t.Val())
|
pushtype(r, t.Elem())
|
||||||
r = typecheck(r, Erv)
|
r = typecheck(r, Erv)
|
||||||
r = defaultlit(r, t.Val())
|
r = defaultlit(r, t.Elem())
|
||||||
l.Right = assignconv(r, t.Val(), "map value")
|
l.Right = assignconv(r, t.Elem(), "map value")
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = OMAPLIT
|
n.Op = OMAPLIT
|
||||||
|
|
|
||||||
|
|
@ -822,7 +822,7 @@ opswitch:
|
||||||
// a = *var
|
// a = *var
|
||||||
a := n.List.First()
|
a := n.List.First()
|
||||||
|
|
||||||
if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/map.go:maxZero
|
if w := t.Elem().Width; w <= 1024 { // 1024 must match ../../../../runtime/map.go:maxZero
|
||||||
fn := mapfn(mapaccess2[fast], t)
|
fn := mapfn(mapaccess2[fast], t)
|
||||||
r = mkcall1(fn, fn.Type.Results(), init, typename(t), r.Left, key)
|
r = mkcall1(fn, fn.Type.Results(), init, typename(t), r.Left, key)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -842,7 +842,7 @@ opswitch:
|
||||||
|
|
||||||
// don't generate a = *var if a is _
|
// don't generate a = *var if a is _
|
||||||
if !a.isBlank() {
|
if !a.isBlank() {
|
||||||
var_ := temp(types.NewPtr(t.Val()))
|
var_ := temp(types.NewPtr(t.Elem()))
|
||||||
var_.SetTypecheck(1)
|
var_.SetTypecheck(1)
|
||||||
var_.SetNonNil(true) // mapaccess always returns a non-nil pointer
|
var_.SetNonNil(true) // mapaccess always returns a non-nil pointer
|
||||||
n.List.SetFirst(var_)
|
n.List.SetFirst(var_)
|
||||||
|
|
@ -1196,17 +1196,17 @@ opswitch:
|
||||||
key = nod(OADDR, key, nil)
|
key = nod(OADDR, key, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/map.go:maxZero
|
if w := t.Elem().Width; w <= 1024 { // 1024 must match ../../../../runtime/map.go:maxZero
|
||||||
n = mkcall1(mapfn(mapaccess1[fast], t), types.NewPtr(t.Val()), init, typename(t), map_, key)
|
n = mkcall1(mapfn(mapaccess1[fast], t), types.NewPtr(t.Elem()), init, typename(t), map_, key)
|
||||||
} else {
|
} else {
|
||||||
z := zeroaddr(w)
|
z := zeroaddr(w)
|
||||||
n = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Val()), init, typename(t), map_, key, z)
|
n = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Elem()), init, typename(t), map_, key, z)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n.Type = types.NewPtr(t.Val())
|
n.Type = types.NewPtr(t.Elem())
|
||||||
n.SetNonNil(true) // mapaccess1* and mapassign always return non-nil pointers.
|
n.SetNonNil(true) // mapaccess1* and mapassign always return non-nil pointers.
|
||||||
n = nod(OIND, n, nil)
|
n = nod(OIND, n, nil)
|
||||||
n.Type = t.Val()
|
n.Type = t.Elem()
|
||||||
n.SetTypecheck(1)
|
n.SetTypecheck(1)
|
||||||
|
|
||||||
case ORECV:
|
case ORECV:
|
||||||
|
|
@ -1498,7 +1498,7 @@ opswitch:
|
||||||
// Call runtime.makehmap to allocate an
|
// Call runtime.makehmap to allocate an
|
||||||
// hmap on the heap and initialize hmap's hash0 field.
|
// hmap on the heap and initialize hmap's hash0 field.
|
||||||
fn := syslook("makemap_small")
|
fn := syslook("makemap_small")
|
||||||
fn = substArgTypes(fn, t.Key(), t.Val())
|
fn = substArgTypes(fn, t.Key(), t.Elem())
|
||||||
n = mkcall1(fn, n.Type, init)
|
n = mkcall1(fn, n.Type, init)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1525,7 +1525,7 @@ opswitch:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := syslook(fnname)
|
fn := syslook(fnname)
|
||||||
fn = substArgTypes(fn, hmapType, t.Key(), t.Val())
|
fn = substArgTypes(fn, hmapType, t.Key(), t.Elem())
|
||||||
n = mkcall1(fn, n.Type, init, typename(n.Type), conv(hint, argtype), h)
|
n = mkcall1(fn, n.Type, init, typename(n.Type), conv(hint, argtype), h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2792,7 +2792,7 @@ func mapfn(name string, t *types.Type) *Node {
|
||||||
Fatalf("mapfn %v", t)
|
Fatalf("mapfn %v", t)
|
||||||
}
|
}
|
||||||
fn := syslook(name)
|
fn := syslook(name)
|
||||||
fn = substArgTypes(fn, t.Key(), t.Val(), t.Key(), t.Val())
|
fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key(), t.Elem())
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2801,7 +2801,7 @@ func mapfndel(name string, t *types.Type) *Node {
|
||||||
Fatalf("mapfn %v", t)
|
Fatalf("mapfn %v", t)
|
||||||
}
|
}
|
||||||
fn := syslook(name)
|
fn := syslook(name)
|
||||||
fn = substArgTypes(fn, t.Key(), t.Val(), t.Key())
|
fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key())
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2828,7 +2828,7 @@ var mapdelete = mkmapnames("mapdelete", "")
|
||||||
|
|
||||||
func mapfast(t *types.Type) int {
|
func mapfast(t *types.Type) int {
|
||||||
// Check ../../runtime/map.go:maxValueSize before changing.
|
// Check ../../runtime/map.go:maxValueSize before changing.
|
||||||
if t.Val().Width > 128 {
|
if t.Elem().Width > 128 {
|
||||||
return mapslow
|
return mapslow
|
||||||
}
|
}
|
||||||
switch algtype(t.Key()) {
|
switch algtype(t.Key()) {
|
||||||
|
|
|
||||||
|
|
@ -219,8 +219,8 @@ func (t *Type) SetPkg(pkg *Pkg) {
|
||||||
|
|
||||||
// Map contains Type fields specific to maps.
|
// Map contains Type fields specific to maps.
|
||||||
type Map struct {
|
type Map struct {
|
||||||
Key *Type // Key type
|
Key *Type // Key type
|
||||||
Val *Type // Val (elem) type
|
Elem *Type // Val (elem) type
|
||||||
|
|
||||||
Bucket *Type // internal struct type representing a hash bucket
|
Bucket *Type // internal struct type representing a hash bucket
|
||||||
Hmap *Type // internal struct type representing the Hmap (map header object)
|
Hmap *Type // internal struct type representing the Hmap (map header object)
|
||||||
|
|
@ -539,7 +539,7 @@ func NewMap(k, v *Type) *Type {
|
||||||
t := New(TMAP)
|
t := New(TMAP)
|
||||||
mt := t.MapType()
|
mt := t.MapType()
|
||||||
mt.Key = k
|
mt.Key = k
|
||||||
mt.Val = v
|
mt.Elem = v
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -650,11 +650,11 @@ func SubstAny(t *Type, types *[]*Type) *Type {
|
||||||
|
|
||||||
case TMAP:
|
case TMAP:
|
||||||
key := SubstAny(t.Key(), types)
|
key := SubstAny(t.Key(), types)
|
||||||
val := SubstAny(t.Val(), types)
|
elem := SubstAny(t.Elem(), types)
|
||||||
if key != t.Key() || val != t.Val() {
|
if key != t.Key() || elem != t.Elem() {
|
||||||
t = t.copy()
|
t = t.copy()
|
||||||
t.Extra.(*Map).Key = key
|
t.Extra.(*Map).Key = key
|
||||||
t.Extra.(*Map).Val = val
|
t.Extra.(*Map).Elem = elem
|
||||||
}
|
}
|
||||||
|
|
||||||
case TFUNC:
|
case TFUNC:
|
||||||
|
|
@ -787,14 +787,8 @@ func (t *Type) Key() *Type {
|
||||||
return t.Extra.(*Map).Key
|
return t.Extra.(*Map).Key
|
||||||
}
|
}
|
||||||
|
|
||||||
// Val returns the value type of map type t.
|
|
||||||
func (t *Type) Val() *Type {
|
|
||||||
t.wantEtype(TMAP)
|
|
||||||
return t.Extra.(*Map).Val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Elem returns the type of elements of t.
|
// Elem returns the type of elements of t.
|
||||||
// Usable with pointers, channels, arrays, and slices.
|
// Usable with pointers, channels, arrays, slices, and maps.
|
||||||
func (t *Type) Elem() *Type {
|
func (t *Type) Elem() *Type {
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
case TPTR32, TPTR64:
|
case TPTR32, TPTR64:
|
||||||
|
|
@ -805,6 +799,8 @@ func (t *Type) Elem() *Type {
|
||||||
return t.Extra.(Slice).Elem
|
return t.Extra.(Slice).Elem
|
||||||
case TCHAN:
|
case TCHAN:
|
||||||
return t.Extra.(*Chan).Elem
|
return t.Extra.(*Chan).Elem
|
||||||
|
case TMAP:
|
||||||
|
return t.Extra.(*Map).Elem
|
||||||
}
|
}
|
||||||
Fatalf("Type.Elem %s", t.Etype)
|
Fatalf("Type.Elem %s", t.Etype)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -1104,7 +1100,7 @@ func (t *Type) cmp(x *Type) Cmp {
|
||||||
if c := t.Key().cmp(x.Key()); c != CMPeq {
|
if c := t.Key().cmp(x.Key()); c != CMPeq {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
return t.Val().cmp(x.Val())
|
return t.Elem().cmp(x.Elem())
|
||||||
|
|
||||||
case TPTR32, TPTR64, TSLICE:
|
case TPTR32, TPTR64, TSLICE:
|
||||||
// No special cases for these, they are handled
|
// No special cases for these, they are handled
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue