mirror of
https://github.com/golang/go
synced 2024-11-18 04:44:46 -07:00
go/types: don't update package-external types when checking validity
The recently added type-validity check uses a new field of Named types for marking (to detect cycles). That field was modified even if the type was not part of the current package or belonged to the Universe scope (error type). This led to race conditions if the package's type was imported by multiple, concurrently type-checked packages. A test would be nice but it's a bit cumbersome to set one up. Verified manually that package-external types are left alone. Fixes #35049. Change-Id: I51686bef47fcca48b99b91ecb1b2e9d58e135ea6 Reviewed-on: https://go-review.googlesource.com/c/go/+/202483 Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
parent
19d2a1cc2c
commit
51504f0a2d
@ -311,19 +311,29 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case *Named:
|
case *Named:
|
||||||
|
// don't touch the type if it is from a different package or the Universe scope
|
||||||
|
// (doing so would lead to a race condition - was issue #35049)
|
||||||
|
if t.obj.pkg != check.pkg {
|
||||||
|
return valid
|
||||||
|
}
|
||||||
|
|
||||||
// don't report a 2nd error if we already know the type is invalid
|
// don't report a 2nd error if we already know the type is invalid
|
||||||
// (e.g., if a cycle was detected earlier, via Checker.underlying).
|
// (e.g., if a cycle was detected earlier, via Checker.underlying).
|
||||||
if t.underlying == Typ[Invalid] {
|
if t.underlying == Typ[Invalid] {
|
||||||
t.info = invalid
|
t.info = invalid
|
||||||
return invalid
|
return invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
switch t.info {
|
switch t.info {
|
||||||
case unknown:
|
case unknown:
|
||||||
t.info = marked
|
t.info = marked
|
||||||
t.info = check.validType(t.orig, append(path, t.obj))
|
t.info = check.validType(t.orig, append(path, t.obj)) // only types of current package added to path
|
||||||
case marked:
|
case marked:
|
||||||
// cycle detected
|
// cycle detected
|
||||||
for i, tn := range path {
|
for i, tn := range path {
|
||||||
|
if t.obj.pkg != check.pkg {
|
||||||
|
panic("internal error: type cycle via package-external type")
|
||||||
|
}
|
||||||
if tn == t.obj {
|
if tn == t.obj {
|
||||||
check.cycleError(path[i:])
|
check.cycleError(path[i:])
|
||||||
t.info = invalid
|
t.info = invalid
|
||||||
|
Loading…
Reference in New Issue
Block a user