Skip to content

Commit 8257ad0

Browse files
griesemerjproberts
authored andcommitted
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 golang#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 d211e93 commit 8257ad0

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)