mirror of
https://github.com/golang/go
synced 2024-09-29 14:14:29 -06:00
cmd/compile/internal/types: use Type.LinkString in TypeHash
Now that Type.LinkString always returns a fully unique string ID, we can use it in TypeHash to avoid collisions between instantiations of the same generic type. Updates #51734. Change-Id: I38cb396c88259be7afa44bd4333124ca98666c3f Reviewed-on: https://go-review.googlesource.com/c/go/+/393716 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
d81dd12906
commit
a900a176bf
@ -72,7 +72,6 @@ const (
|
|||||||
fmtDebug
|
fmtDebug
|
||||||
fmtTypeID
|
fmtTypeID
|
||||||
fmtTypeIDName
|
fmtTypeIDName
|
||||||
fmtTypeIDHash
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Sym
|
// Sym
|
||||||
@ -144,18 +143,6 @@ func symfmt(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) {
|
|||||||
if q := pkgqual(s.Pkg, verb, mode); q != "" {
|
if q := pkgqual(s.Pkg, verb, mode); q != "" {
|
||||||
b.WriteString(q)
|
b.WriteString(q)
|
||||||
b.WriteByte('.')
|
b.WriteByte('.')
|
||||||
switch mode {
|
|
||||||
case fmtTypeIDHash:
|
|
||||||
// If name is a generic instantiation, don't hash the instantiating types.
|
|
||||||
// This isn't great, but it is safe. If we hash the instantiating types, then
|
|
||||||
// we need to make sure they have just the package name. At this point, they
|
|
||||||
// either have "", or the whole package path, and it is hard to reconcile
|
|
||||||
// the two without depending on -p (which we might do someday).
|
|
||||||
// See issue 51250.
|
|
||||||
if i := strings.Index(name, "["); i >= 0 {
|
|
||||||
name = name[:i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
b.WriteString(name)
|
b.WriteString(name)
|
||||||
}
|
}
|
||||||
@ -183,7 +170,7 @@ func pkgqual(pkg *Pkg, verb rune, mode fmtMode) string {
|
|||||||
case fmtDebug:
|
case fmtDebug:
|
||||||
return pkg.Name
|
return pkg.Name
|
||||||
|
|
||||||
case fmtTypeIDName, fmtTypeIDHash:
|
case fmtTypeIDName:
|
||||||
// dcommontype, typehash
|
// dcommontype, typehash
|
||||||
return pkg.Name
|
return pkg.Name
|
||||||
|
|
||||||
@ -329,7 +316,7 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type
|
|||||||
if t == AnyType || t == ByteType || t == RuneType {
|
if t == AnyType || t == ByteType || t == RuneType {
|
||||||
// in %-T mode collapse predeclared aliases with their originals.
|
// in %-T mode collapse predeclared aliases with their originals.
|
||||||
switch mode {
|
switch mode {
|
||||||
case fmtTypeIDName, fmtTypeIDHash, fmtTypeID:
|
case fmtTypeIDName, fmtTypeID:
|
||||||
t = Types[t.Kind()]
|
t = Types[t.Kind()]
|
||||||
default:
|
default:
|
||||||
sconv2(b, t.Sym(), 'S', mode)
|
sconv2(b, t.Sym(), 'S', mode)
|
||||||
@ -420,7 +407,7 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type
|
|||||||
case TPTR:
|
case TPTR:
|
||||||
b.WriteByte('*')
|
b.WriteByte('*')
|
||||||
switch mode {
|
switch mode {
|
||||||
case fmtTypeID, fmtTypeIDName, fmtTypeIDHash:
|
case fmtTypeID, fmtTypeIDName:
|
||||||
if verb == 'S' {
|
if verb == 'S' {
|
||||||
tconv2(b, t.Elem(), 'S', mode, visited)
|
tconv2(b, t.Elem(), 'S', mode, visited)
|
||||||
return
|
return
|
||||||
@ -482,7 +469,7 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type
|
|||||||
case IsExported(f.Sym.Name):
|
case IsExported(f.Sym.Name):
|
||||||
sconv2(b, f.Sym, 'S', mode)
|
sconv2(b, f.Sym, 'S', mode)
|
||||||
default:
|
default:
|
||||||
if mode != fmtTypeIDName && mode != fmtTypeIDHash {
|
if mode != fmtTypeIDName {
|
||||||
mode = fmtTypeID
|
mode = fmtTypeID
|
||||||
}
|
}
|
||||||
sconv2(b, f.Sym, 'v', mode)
|
sconv2(b, f.Sym, 'v', mode)
|
||||||
@ -552,7 +539,7 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type
|
|||||||
b.WriteByte(byte(open))
|
b.WriteByte(byte(open))
|
||||||
fieldVerb := 'v'
|
fieldVerb := 'v'
|
||||||
switch mode {
|
switch mode {
|
||||||
case fmtTypeID, fmtTypeIDName, fmtTypeIDHash, fmtGo:
|
case fmtTypeID, fmtTypeIDName, fmtGo:
|
||||||
// no argument names on function signature, and no "noescape"/"nosplit" tags
|
// no argument names on function signature, and no "noescape"/"nosplit" tags
|
||||||
fieldVerb = 'S'
|
fieldVerb = 'S'
|
||||||
}
|
}
|
||||||
@ -686,7 +673,7 @@ func fldconv(b *bytes.Buffer, f *Field, verb rune, mode fmtMode, visited map[*Ty
|
|||||||
if name == ".F" {
|
if name == ".F" {
|
||||||
name = "F" // Hack for toolstash -cmp.
|
name = "F" // Hack for toolstash -cmp.
|
||||||
}
|
}
|
||||||
if !IsExported(name) && mode != fmtTypeIDName && mode != fmtTypeIDHash {
|
if !IsExported(name) && mode != fmtTypeIDName {
|
||||||
name = sconv(s, 0, mode) // qualify non-exported names (used on structs, not on funarg)
|
name = sconv(s, 0, mode) // qualify non-exported names (used on structs, not on funarg)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -754,7 +741,7 @@ func FmtConst(v constant.Value, sharp bool) string {
|
|||||||
|
|
||||||
// TypeHash computes a hash value for type t to use in type switch statements.
|
// TypeHash computes a hash value for type t to use in type switch statements.
|
||||||
func TypeHash(t *Type) uint32 {
|
func TypeHash(t *Type) uint32 {
|
||||||
p := tconv(t, 0, fmtTypeIDHash)
|
p := t.LinkString()
|
||||||
|
|
||||||
// Using SHA256 is overkill, but reduces accidental collisions.
|
// Using SHA256 is overkill, but reduces accidental collisions.
|
||||||
h := notsha256.Sum256([]byte(p))
|
h := notsha256.Sum256([]byte(p))
|
||||||
|
Loading…
Reference in New Issue
Block a user