]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types: use a global atomic counter for type parameter ids
authorRob Findley <rfindley@google.com>
Wed, 28 Apr 2021 14:02:16 +0000 (10:02 -0400)
committerRobert Findley <rfindley@google.com>
Wed, 28 Apr 2021 19:52:58 +0000 (19:52 +0000)
This is a 1:1 port of CL 309830 to go/types.

Change-Id: Ibf709f8194dd5e93a87145e5f9db674ce93af529
Reviewed-on: https://go-review.googlesource.com/c/go/+/314594
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/api_test.go
src/go/types/check.go
src/go/types/type.go
src/go/types/types_test.go [new file with mode: 0644]

index 3438d790246cb46ad131ff5ef1036fd7b8fa83f2..5ac91bedd2b057652ce57e2acda844bb0ad3a3e2 100644 (file)
@@ -353,6 +353,7 @@ func TestTypesInfo(t *testing.T) {
        }
 
        for _, test := range tests {
+               ResetId() // avoid renumbering of type parameter ids when adding tests
                if strings.HasPrefix(test.src, genericPkg) && !typeparams.Enabled {
                        continue
                }
index 83568c9353d70355283be35805e4c745c8bda185..1f64d3e3c3a6edb9acd4ddfc61caddc39b163342 100644 (file)
@@ -86,7 +86,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][]token.Pos // maps interface types to lists of embedded interface positions
@@ -191,7 +190,6 @@ func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Ch
                pkg:     pkg,
                Info:    info,
                version: version,
-               nextId:  1,
                objMap:  make(map[Object]*declInfo),
                impMap:  make(map[importKey]*Package),
                posMap:  make(map[*Interface][]token.Pos),
index 21d49de3aae6caae0cc9ff14b413727d8551c134..3303cfc077424f64fc68e6809810780a461d809a 100644 (file)
@@ -7,6 +7,7 @@ package types
 import (
        "fmt"
        "go/token"
+       "sync/atomic"
 )
 
 // A Type represents a type of Go.
@@ -715,6 +716,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
@@ -727,8 +737,7 @@ type _TypeParam struct {
 // 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
        }
diff --git a/src/go/types/types_test.go b/src/go/types/types_test.go
new file mode 100644 (file)
index 0000000..fd9462c
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import "sync/atomic"
+
+// 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) }