]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: use Type.LinkString for map keys
authorMatthew Dempsky <mdempsky@google.com>
Fri, 25 Jun 2021 17:15:40 +0000 (10:15 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 25 Jun 2021 23:10:23 +0000 (23:10 +0000)
This CL changes typecheck and order to use Type.LinkString for
computing map keys instead of Type.NameString. As mentioned in the
LinkString docs (added by the previous CL), LinkString reliably maps
type identity to string equality as long as the LinkString calls all
happen within the same compilation unit (which they do here).

This eliminates the need for subsequent types.Identical checks.

Change-Id: I32ff591e69d6f23f2dc6ebd5af343618ebe89013
Reviewed-on: https://go-review.googlesource.com/c/go/+/330911
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/reflectdata/reflect.go
src/cmd/compile/internal/typecheck/stmt.go
src/cmd/compile/internal/walk/order.go

index 316c7eb2935ed6e060e4518263faee88ffc20cd3..351aaab399a71544bba1d722549b8b04ae44baf7 100644 (file)
@@ -1388,7 +1388,7 @@ func WriteBasicTypes() {
 
 type typeAndStr struct {
        t       *types.Type
-       short   string
+       short   string // "short" here means NameString
        regular string
 }
 
@@ -1401,8 +1401,13 @@ func (a typesByString) Less(i, j int) bool {
        }
        // When the only difference between the types is whether
        // they refer to byte or uint8, such as **byte vs **uint8,
-       // the types' ShortStrings can be identical.
+       // the types' NameStrings can be identical.
        // To preserve deterministic sort ordering, sort these by String().
+       //
+       // TODO(mdempsky): This all seems suspect. Using LinkString would
+       // avoid naming collisions, and there shouldn't be a reason to care
+       // about "byte" vs "uint8": they share the same runtime type
+       // descriptor anyway.
        if a[i].regular != a[j].regular {
                return a[i].regular < a[j].regular
        }
index 313491ba0b8e4336dc7e3e7b1ebf8d896f8b722d..54cf508acc1a645e7651d72cb5352e69f1dc8738 100644 (file)
@@ -662,29 +662,18 @@ func tcSwitchType(n *ir.SwitchStmt) {
 }
 
 type typeSet struct {
-       m map[string][]typeSetEntry
-}
-
-type typeSetEntry struct {
-       pos src.XPos
-       typ *types.Type
+       m map[string]src.XPos
 }
 
 func (s *typeSet) add(pos src.XPos, typ *types.Type) {
        if s.m == nil {
-               s.m = make(map[string][]typeSetEntry)
+               s.m = make(map[string]src.XPos)
        }
 
-       // LongString does not uniquely identify types, so we need to
-       // disambiguate collisions with types.Identical.
-       // TODO(mdempsky): Add a method that *is* unique.
-       ls := typ.NameString()
-       prevs := s.m[ls]
-       for _, prev := range prevs {
-               if types.Identical(typ, prev.typ) {
-                       base.ErrorfAt(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, base.FmtPos(prev.pos))
-                       return
-               }
+       ls := typ.LinkString()
+       if prev, ok := s.m[ls]; ok {
+               base.ErrorfAt(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, base.FmtPos(prev))
+               return
        }
-       s.m[ls] = append(prevs, typeSetEntry{pos, typ})
+       s.m[ls] = pos
 }
index 59701613c35564276be9266dae5705fe3ab178dc..9912feba637d277407b394495d8730d5bc249e18 100644 (file)
@@ -51,7 +51,7 @@ import (
 type orderState struct {
        out  []ir.Node             // list of generated statements
        temp []*ir.Name            // stack of temporary variables
-       free map[string][]*ir.Name // free list of unused temporaries, by type.LongString().
+       free map[string][]*ir.Name // free list of unused temporaries, by type.LinkString().
        edit func(ir.Node) ir.Node // cached closure of o.exprNoLHS
 }
 
@@ -76,20 +76,14 @@ func (o *orderState) append(stmt ir.Node) {
 // If clear is true, newTemp emits code to zero the temporary.
 func (o *orderState) newTemp(t *types.Type, clear bool) *ir.Name {
        var v *ir.Name
-       // Note: LongString is close to the type equality we want,
-       // but not exactly. We still need to double-check with types.Identical.
-       key := t.NameString()
-       a := o.free[key]
-       for i, n := range a {
-               if types.Identical(t, n.Type()) {
-                       v = a[i]
-                       a[i] = a[len(a)-1]
-                       a = a[:len(a)-1]
-                       o.free[key] = a
-                       break
+       key := t.LinkString()
+       if a := o.free[key]; len(a) > 0 {
+               v = a[len(a)-1]
+               if !types.Identical(t, v.Type()) {
+                       base.Fatalf("expected %L to have type %v", v, t)
                }
-       }
-       if v == nil {
+               o.free[key] = a[:len(a)-1]
+       } else {
                v = typecheck.Temp(t)
        }
        if clear {
@@ -370,7 +364,7 @@ func (o *orderState) markTemp() ordermarker {
 // which must have been returned by markTemp.
 func (o *orderState) popTemp(mark ordermarker) {
        for _, n := range o.temp[mark:] {
-               key := n.Type().NameString()
+               key := n.Type().LinkString()
                o.free[key] = append(o.free[key], n)
        }
        o.temp = o.temp[:mark]