mirror of
https://github.com/golang/go
synced 2024-11-26 04:58:00 -07:00
cmd/compile/internal/types2: use a global atomic counter for type parameter ids
This avoids a dependency on a *Checker when we create type parameters outside the type checker proper, e.g. in an importer. There may be better solutions but this does the trick for now. Change-Id: Icf22c934970cb04c88c2729555ae6a79ef5a2245 Reviewed-on: https://go-review.googlesource.com/c/go/+/309830 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
34620364cb
commit
8dcc071063
@ -349,6 +349,7 @@ func TestTypesInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
ResetId() // avoid renumbering of type parameter ids when adding tests
|
||||
info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
|
||||
var name string
|
||||
if strings.HasPrefix(test.src, brokenPkg) {
|
||||
|
@ -83,7 +83,6 @@ type Checker struct {
|
||||
pkg *Package
|
||||
*Info
|
||||
version version // accepted language version
|
||||
nextId uint64 // unique Id for type parameters (first valid Id is 1)
|
||||
objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info
|
||||
impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package
|
||||
posMap map[*Interface][]syntax.Pos // maps interface types to lists of embedded interface positions
|
||||
@ -178,7 +177,6 @@ func NewChecker(conf *Config, pkg *Package, info *Info) *Checker {
|
||||
pkg: pkg,
|
||||
Info: info,
|
||||
version: version,
|
||||
nextId: 1,
|
||||
objMap: make(map[Object]*declInfo),
|
||||
impMap: make(map[importKey]*Package),
|
||||
posMap: make(map[*Interface][]syntax.Pos),
|
||||
|
@ -7,6 +7,7 @@ package types2
|
||||
import (
|
||||
"cmd/compile/internal/syntax"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// A Type represents a type of Go.
|
||||
@ -718,6 +719,15 @@ func (t *Named) AddMethod(m *Func) {
|
||||
}
|
||||
}
|
||||
|
||||
// Note: This is a uint32 rather than a uint64 because the
|
||||
// respective 64 bit atomic instructions are not available
|
||||
// on all platforms.
|
||||
var lastId uint32
|
||||
|
||||
// nextId returns a value increasing monotonically by 1 with
|
||||
// each call, starting with 1. It may be called concurrently.
|
||||
func nextId() uint64 { return uint64(atomic.AddUint32(&lastId, 1)) }
|
||||
|
||||
// A TypeParam represents a type parameter type.
|
||||
type TypeParam struct {
|
||||
check *Checker // for lazy type bound completion
|
||||
@ -733,8 +743,7 @@ func (t *TypeParam) Obj() *TypeName { return t.obj }
|
||||
// NewTypeParam returns a new TypeParam.
|
||||
func (check *Checker) NewTypeParam(obj *TypeName, index int, bound Type) *TypeParam {
|
||||
assert(bound != nil)
|
||||
typ := &TypeParam{check: check, id: check.nextId, obj: obj, index: index, bound: bound}
|
||||
check.nextId++
|
||||
typ := &TypeParam{check: check, id: nextId(), obj: obj, index: index, bound: bound}
|
||||
if obj.typ == nil {
|
||||
obj.typ = typ
|
||||
}
|
||||
|
@ -4,6 +4,14 @@
|
||||
|
||||
package types2
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
func init() {
|
||||
acceptMethodTypeParams = true
|
||||
}
|
||||
|
||||
// Upon calling ResetId, nextId starts with 1 again.
|
||||
// It may be called concurrently. This is only needed
|
||||
// for tests where we may want to have a consistent
|
||||
// numbering for each individual test case.
|
||||
func ResetId() { atomic.StoreUint32(&lastId, 0) }
|
||||
|
Loading…
Reference in New Issue
Block a user