aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/compile/internal/noder/reader.go4
-rw-r--r--src/cmd/compile/internal/reflectdata/reflect.go8
-rw-r--r--src/cmd/compile/internal/typecheck/stmt.go2
-rw-r--r--src/cmd/compile/internal/types/fmt.go38
-rw-r--r--src/cmd/compile/internal/types/type.go2
-rw-r--r--src/cmd/compile/internal/walk/order.go4
6 files changed, 39 insertions, 19 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index 0423fcce98..459e1d1703 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -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)
diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go
index 8421e36b3d..316c7eb293 100644
--- a/src/cmd/compile/internal/reflectdata/reflect.go
+++ b/src/cmd/compile/internal/reflectdata/reflect.go
@@ -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 {
diff --git a/src/cmd/compile/internal/typecheck/stmt.go b/src/cmd/compile/internal/typecheck/stmt.go
index cd00f1b3d1..313491ba0b 100644
--- a/src/cmd/compile/internal/typecheck/stmt.go
+++ b/src/cmd/compile/internal/typecheck/stmt.go
@@ -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) {
diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go
index b4d1f6c8bb..095b795d03 100644
--- a/src/cmd/compile/internal/types/fmt.go
+++ b/src/cmd/compile/internal/types/fmt.go
@@ -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))
diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go
index 075009d6a3..7f75000797 100644
--- a/src/cmd/compile/internal/types/type.go
+++ b/src/cmd/compile/internal/types/type.go
@@ -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
diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go
index 62d9b95be9..59701613c3 100644
--- a/src/cmd/compile/internal/walk/order.go
+++ b/src/cmd/compile/internal/walk/order.go
@@ -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]