]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: rename types.Type.{Short,Long}String to {Link,Name...
authorMatthew Dempsky <mdempsky@google.com>
Fri, 25 Jun 2021 17:04:51 +0000 (10:04 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 25 Jun 2021 23:10:17 +0000 (23:10 +0000)
The original names "ShortString" and "LongString" refer back to the
fmt verbs used to request their formatting styles. However, I always
get confused working with them, in particular because (1) the
"ShortString" description, which uses package-path qualification, is
actually generally longer than the "LongString" description, which
uses package-name qualification; and (2) the documentation mentions
how they're often used, but doesn't actually describe why they're safe
for those purposes.

This CL renames them to "LinkString" and "NameString", respectively,
based on their primary use cases. It also attempts to more completely
describe the strings they return and how they can be used correctly.

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

index 0423fcce987661e679e914c35fee2800fc7d7a93..459e1d1703c0e256fc13ef76de8862a86c4cbe9f 100644 (file)
@@ -631,7 +631,7 @@ func (r *reader) mangle(sym *types.Sym) *types.Sym {
                        }
                        // TODO(mdempsky): We need the linker to replace "" in the symbol
                        // names here.
-                       buf.WriteString(targ.ShortString())
+                       buf.WriteString(targ.LinkString())
                }
        }
        buf.WriteByte(']')
@@ -2041,7 +2041,7 @@ func (r *reader) wrapTypes(target *ir.Package) {
        seen := make(map[string]*types.Type)
        for _, typ := range needWrapperTypes {
                if typ.Sym() == nil {
-                       key := typ.ShortString()
+                       key := typ.LinkString()
                        if prev := seen[key]; prev != nil {
                                if !types.Identical(typ, prev) {
                                        base.Fatalf("collision: types %v and %v have short string %q", typ, prev, key)
index 8421e36b3dde38af76064ba113d959a4166971ef..316c7eb2935ed6e060e4518263faee88ffc20cd3 100644 (file)
@@ -717,7 +717,7 @@ func dcommontype(lsym *obj.LSym, t *types.Type) int {
        }
 
        exported := false
-       p := t.LongString()
+       p := t.NameString()
        // If we're writing out type T,
        // we are very likely to write out type *T as well.
        // Use the string "*T"[1:] for "T", so that the two
@@ -781,11 +781,11 @@ func dcommontype(lsym *obj.LSym, t *types.Type) int {
 // TrackSym returns the symbol for tracking use of field/method f, assumed
 // to be a member of struct/interface type t.
 func TrackSym(t *types.Type, f *types.Field) *obj.LSym {
-       return base.PkgLinksym("go.track", t.ShortString()+"."+f.Sym.Name, obj.ABI0)
+       return base.PkgLinksym("go.track", t.LinkString()+"."+f.Sym.Name, obj.ABI0)
 }
 
 func TypeSymPrefix(prefix string, t *types.Type) *types.Sym {
-       p := prefix + "." + t.ShortString()
+       p := prefix + "." + t.LinkString()
        s := types.TypeSymLookup(p)
 
        // This function is for looking up type-related generated functions
@@ -833,7 +833,7 @@ func TypePtr(t *types.Type) *ir.AddrExpr {
 // ITabAddr returns an expression representing a pointer to the itab
 // for concrete type typ implementing interface iface.
 func ITabAddr(typ, iface *types.Type) *ir.AddrExpr {
-       s, existed := ir.Pkgs.Itab.LookupOK(typ.ShortString() + "," + iface.ShortString())
+       s, existed := ir.Pkgs.Itab.LookupOK(typ.LinkString() + "," + iface.LinkString())
        lsym := s.Linksym()
 
        if !existed {
index cd00f1b3d117f37585134a809d531799e535d351..313491ba0b8e4336dc7e3e7b1ebf8d896f8b722d 100644 (file)
@@ -678,7 +678,7 @@ func (s *typeSet) add(pos src.XPos, typ *types.Type) {
        // 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.LongString()
+       ls := typ.NameString()
        prevs := s.m[ls]
        for _, prev := range prevs {
                if types.Identical(typ, prev.typ) {
index b4d1f6c8bbd900e3dc0e2c7a8cee751a7292851b..095b795d0366f214beab85d8de317a38eb0e78b7 100644 (file)
@@ -242,17 +242,37 @@ func (t *Type) String() string {
        return tconv(t, 0, fmtGo)
 }
 
-// ShortString generates a short description of t.
-// It is used in autogenerated method names, reflection,
-// and itab names.
-func (t *Type) ShortString() string {
+// LinkString returns an unexpanded string description of t, suitable
+// for use in link symbols. "Unexpanded" here means that the
+// description uses `"".` to qualify identifiers from the current
+// package, and "expansion" refers to the renaming step performed by
+// the linker to replace these qualifiers with proper `path/to/pkg.`
+// qualifiers.
+//
+// After expansion, the description corresponds to type identity. That
+// is, for any pair of types t1 and t2, Identical(t1, t2) and
+// expand(t1.LinkString()) == expand(t2.LinkString()) report the same
+// value.
+//
+// Within a single compilation unit, LinkString always returns the
+// same unexpanded description for identical types. Thus it's safe to
+// use as a map key to implement a type-identity-keyed map. However,
+// make sure all LinkString calls used for this purpose happen within
+// the same compile process; the string keys are not stable across
+// multiple processes.
+func (t *Type) LinkString() string {
        return tconv(t, 0, fmtTypeID)
 }
 
-// LongString generates a complete description of t.
-// It is useful for reflection,
-// or when a unique fingerprint or hash of a type is required.
-func (t *Type) LongString() string {
+// NameString generates a user-readable, mostly unique string
+// description of t. NameString always returns the same description
+// for identical types, even across compilation units.
+//
+// NameString qualifies identifiers by package name, so it has
+// collisions when different packages share the same names and
+// identifiers. It also does not distinguish function-scope defined
+// types from package-scoped defined types or from each other.
+func (t *Type) NameString() string {
        return tconv(t, 0, fmtTypeIDName)
 }
 
@@ -677,7 +697,7 @@ func FmtConst(v constant.Value, sharp bool) string {
 
 // TypeHash computes a hash value for type t to use in type switch statements.
 func TypeHash(t *Type) uint32 {
-       p := t.LongString()
+       p := t.NameString()
 
        // Using MD5 is overkill, but reduces accidental collisions.
        h := md5.Sum([]byte(p))
index 075009d6a3b95efde4cd1f1775bf8c1d02cdd992..7f7500079723ff606f84309c4d5dc948ffd62b6c 100644 (file)
@@ -2129,7 +2129,7 @@ func TypeSymLookup(name string) *Sym {
 }
 
 func TypeSymName(t *Type) string {
-       name := t.ShortString()
+       name := t.LinkString()
        // Use a separate symbol name for Noalg types for #17752.
        if TypeHasNoAlg(t) {
                name = "noalg." + name
index 62d9b95be90fab193f872b2a5e750067e2cd15fd..59701613c35564276be9266dae5705fe3ab178dc 100644 (file)
@@ -78,7 +78,7 @@ 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.LongString()
+       key := t.NameString()
        a := o.free[key]
        for i, n := range a {
                if types.Identical(t, n.Type()) {
@@ -370,7 +370,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().LongString()
+               key := n.Type().NameString()
                o.free[key] = append(o.free[key], n)
        }
        o.temp = o.temp[:mark]