Skip to content

Commit 4284d45

Browse files
committed
go/types, types2: use a map instead of a field for marking in validType
With this change validType doesn't modify global state anymore. It also eliminates the need for an extra field in each object. Preparation for fixing issue #48962. Change-Id: If241ec77ff48911d5b43d89adabfb8ef54452c6b Reviewed-on: https://go-review.googlesource.com/c/go/+/378176 Trust: Robert Griesemer <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> Reviewed-by: Robert Findley <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 0328b4f commit 4284d45

File tree

12 files changed

+46
-36
lines changed

12 files changed

+46
-36
lines changed

src/cmd/compile/internal/types2/check.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ type Checker struct {
111111
nextID uint64 // unique Id for type parameters (first valid Id is 1)
112112
objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info
113113
impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package
114+
infoMap map[*Named]typeInfo // maps named types to their associated type info (for cycle detection)
114115

115116
// pkgPathMap maps package names to the set of distinct import paths we've
116117
// seen for that name, anywhere in the import graph. It is used for
@@ -221,6 +222,7 @@ func NewChecker(conf *Config, pkg *Package, info *Info) *Checker {
221222
version: version,
222223
objMap: make(map[Object]*declInfo),
223224
impMap: make(map[importKey]*Package),
225+
infoMap: make(map[*Named]typeInfo),
224226
}
225227
}
226228

src/cmd/compile/internal/types2/decl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
477477

478478
var rhs Type
479479
check.later(func() {
480-
check.validType(obj.typ, nil)
480+
check.validType(obj.typ)
481481
// If typ is local, an error was already reported where typ is specified/defined.
482482
if check.isImportedConstraint(rhs) && !check.allowVersion(check.pkg, 1, 18) {
483483
check.versionErrorf(tdecl.Type, "go1.18", "using type constraint %s", rhs)

src/cmd/compile/internal/types2/named.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
// A Named represents a named (defined) type.
1313
type Named struct {
1414
check *Checker
15-
info typeInfo // for cycle detection
1615
obj *TypeName // corresponding declared object for declared types; placeholder for instantiated types
1716
orig *Named // original, uninstantiated type
1817
fromRHS Type // type (on RHS of declaration) this *Named type is derived from (for cycle reporting)

src/cmd/compile/internal/types2/sizeof_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TestSizeof(t *testing.T) {
3131
{Interface{}, 44, 88},
3232
{Map{}, 16, 32},
3333
{Chan{}, 12, 24},
34-
{Named{}, 68, 128},
34+
{Named{}, 64, 120},
3535
{TypeParam{}, 28, 48},
3636
{term{}, 12, 24},
3737

src/cmd/compile/internal/types2/typexpr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *
487487
}
488488
}
489489

490-
check.validType(inst, nil)
490+
check.validType(inst)
491491
})
492492

493493
return inst

src/cmd/compile/internal/types2/validtype.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44

55
package types2
66

7-
type typeInfo uint
8-
9-
// validType verifies that the given type does not "expand" infinitely
7+
// validType verifies that the given type does not "expand" indefinitely
108
// producing a cycle in the type graph. Cycles are detected by marking
119
// defined types.
1210
// (Cycles involving alias types, as in "type A = [10]A" are detected
1311
// earlier, via the objDecl cycle detection mechanism.)
14-
func (check *Checker) validType(typ Type, path []Object) typeInfo {
12+
func (check *Checker) validType(typ Type) {
13+
check.validType0(typ, nil)
14+
}
15+
16+
type typeInfo uint
17+
18+
func (check *Checker) validType0(typ Type, path []Object) typeInfo {
1519
const (
1620
unknown typeInfo = iota
1721
marked
@@ -21,25 +25,25 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
2125

2226
switch t := typ.(type) {
2327
case *Array:
24-
return check.validType(t.elem, path)
28+
return check.validType0(t.elem, path)
2529

2630
case *Struct:
2731
for _, f := range t.fields {
28-
if check.validType(f.typ, path) == invalid {
32+
if check.validType0(f.typ, path) == invalid {
2933
return invalid
3034
}
3135
}
3236

3337
case *Union:
3438
for _, t := range t.terms {
35-
if check.validType(t.typ, path) == invalid {
39+
if check.validType0(t.typ, path) == invalid {
3640
return invalid
3741
}
3842
}
3943

4044
case *Interface:
4145
for _, etyp := range t.embeddeds {
42-
if check.validType(etyp, path) == invalid {
46+
if check.validType0(etyp, path) == invalid {
4347
return invalid
4448
}
4549
}
@@ -65,14 +69,14 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
6569
// don't report a 2nd error if we already know the type is invalid
6670
// (e.g., if a cycle was detected earlier, via under).
6771
if t.underlying == Typ[Invalid] {
68-
t.info = invalid
72+
check.infoMap[t] = invalid
6973
return invalid
7074
}
7175

72-
switch t.info {
76+
switch check.infoMap[t] {
7377
case unknown:
74-
t.info = marked
75-
t.info = check.validType(t.fromRHS, append(path, t.obj)) // only types of current package added to path
78+
check.infoMap[t] = marked
79+
check.infoMap[t] = check.validType0(t.fromRHS, append(path, t.obj)) // only types of current package added to path
7680
case marked:
7781
// cycle detected
7882
for i, tn := range path {
@@ -81,14 +85,14 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
8185
}
8286
if tn == t.obj {
8387
check.cycleError(path[i:])
84-
t.info = invalid
88+
check.infoMap[t] = invalid
8589
t.underlying = Typ[Invalid]
8690
return invalid
8791
}
8892
}
8993
panic("cycle start not found")
9094
}
91-
return t.info
95+
return check.infoMap[t]
9296
}
9397

9498
return valid

src/go/types/check.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ type Checker struct {
118118
nextID uint64 // unique Id for type parameters (first valid Id is 1)
119119
objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info
120120
impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package
121+
infoMap map[*Named]typeInfo // maps named types to their associated type info (for cycle detection)
121122

122123
// pkgPathMap maps package names to the set of distinct import paths we've
123124
// seen for that name, anywhere in the import graph. It is used for
@@ -229,6 +230,7 @@ func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Ch
229230
version: version,
230231
objMap: make(map[Object]*declInfo),
231232
impMap: make(map[importKey]*Package),
233+
infoMap: make(map[*Named]typeInfo),
232234
}
233235
}
234236

src/go/types/decl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
530530

531531
var rhs Type
532532
check.later(func() {
533-
check.validType(obj.typ, nil)
533+
check.validType(obj.typ)
534534
// If typ is local, an error was already reported where typ is specified/defined.
535535
if check.isImportedConstraint(rhs) && !check.allowVersion(check.pkg, 1, 18) {
536536
check.errorf(tdecl.Type, _UnsupportedFeature, "using type constraint %s requires go1.18 or later", rhs)

src/go/types/named.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
// A Named represents a named (defined) type.
1313
type Named struct {
1414
check *Checker
15-
info typeInfo // for cycle detection
1615
obj *TypeName // corresponding declared object for declared types; placeholder for instantiated types
1716
orig *Named // original, uninstantiated type
1817
fromRHS Type // type (on RHS of declaration) this *Named type is derived of (for cycle reporting)

src/go/types/sizeof_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestSizeof(t *testing.T) {
3030
{Interface{}, 44, 88},
3131
{Map{}, 16, 32},
3232
{Chan{}, 12, 24},
33-
{Named{}, 68, 128},
33+
{Named{}, 64, 120},
3434
{TypeParam{}, 28, 48},
3535
{term{}, 12, 24},
3636

src/go/types/typexpr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *Named) (re
472472
}
473473
}
474474

475-
check.validType(inst, nil)
475+
check.validType(inst)
476476
})
477477

478478
return inst

src/go/types/validtype.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44

55
package types
66

7-
type typeInfo uint
8-
9-
// validType verifies that the given type does not "expand" infinitely
7+
// validType verifies that the given type does not "expand" indefinitely
108
// producing a cycle in the type graph. Cycles are detected by marking
119
// defined types.
1210
// (Cycles involving alias types, as in "type A = [10]A" are detected
1311
// earlier, via the objDecl cycle detection mechanism.)
14-
func (check *Checker) validType(typ Type, path []Object) typeInfo {
12+
func (check *Checker) validType(typ Type) {
13+
check.validType0(typ, nil)
14+
}
15+
16+
type typeInfo uint
17+
18+
func (check *Checker) validType0(typ Type, path []Object) typeInfo {
1519
const (
1620
unknown typeInfo = iota
1721
marked
@@ -21,25 +25,25 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
2125

2226
switch t := typ.(type) {
2327
case *Array:
24-
return check.validType(t.elem, path)
28+
return check.validType0(t.elem, path)
2529

2630
case *Struct:
2731
for _, f := range t.fields {
28-
if check.validType(f.typ, path) == invalid {
32+
if check.validType0(f.typ, path) == invalid {
2933
return invalid
3034
}
3135
}
3236

3337
case *Union:
3438
for _, t := range t.terms {
35-
if check.validType(t.typ, path) == invalid {
39+
if check.validType0(t.typ, path) == invalid {
3640
return invalid
3741
}
3842
}
3943

4044
case *Interface:
4145
for _, etyp := range t.embeddeds {
42-
if check.validType(etyp, path) == invalid {
46+
if check.validType0(etyp, path) == invalid {
4347
return invalid
4448
}
4549
}
@@ -65,14 +69,14 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
6569
// don't report a 2nd error if we already know the type is invalid
6670
// (e.g., if a cycle was detected earlier, via under).
6771
if t.underlying == Typ[Invalid] {
68-
t.info = invalid
72+
check.infoMap[t] = invalid
6973
return invalid
7074
}
7175

72-
switch t.info {
76+
switch check.infoMap[t] {
7377
case unknown:
74-
t.info = marked
75-
t.info = check.validType(t.fromRHS, append(path, t.obj)) // only types of current package added to path
78+
check.infoMap[t] = marked
79+
check.infoMap[t] = check.validType0(t.fromRHS, append(path, t.obj)) // only types of current package added to path
7680
case marked:
7781
// cycle detected
7882
for i, tn := range path {
@@ -81,14 +85,14 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
8185
}
8286
if tn == t.obj {
8387
check.cycleError(path[i:])
84-
t.info = invalid
88+
check.infoMap[t] = invalid
8589
t.underlying = Typ[Invalid]
8690
return invalid
8791
}
8892
}
8993
panic("cycle start not found")
9094
}
91-
return t.info
95+
return check.infoMap[t]
9296
}
9397

9498
return valid

0 commit comments

Comments
 (0)