diff --git a/src/cmd/compile/internal/types2/named.go b/src/cmd/compile/internal/types2/named.go index 26be3104b8c..a75ca75d0cd 100644 --- a/src/cmd/compile/internal/types2/named.go +++ b/src/cmd/compile/internal/types2/named.go @@ -630,6 +630,7 @@ func (n *Named) resolveUnderlying() { t.resolve() t.mu.Lock() defer t.mu.Unlock() + assert(t.fromRHS != nil || t.allowNilRHS) rhs = t.fromRHS @@ -640,6 +641,12 @@ func (n *Named) resolveUnderlying() { // set underlying for all Named types in the chain for t := range seen { + // Careful, t.underlying has lock-free readers. Since we might be racing + // another call to resolveUnderlying, we have to avoid overwriting + // t.underlying. Otherwise, the race detector will be tripped. + if t.stateHas(underlying) { + continue + } t.underlying = u t.setState(underlying) } diff --git a/src/go/types/named.go b/src/go/types/named.go index 79f6fc6a494..7f0e6f4904e 100644 --- a/src/go/types/named.go +++ b/src/go/types/named.go @@ -633,6 +633,7 @@ func (n *Named) resolveUnderlying() { t.resolve() t.mu.Lock() defer t.mu.Unlock() + assert(t.fromRHS != nil || t.allowNilRHS) rhs = t.fromRHS @@ -643,6 +644,12 @@ func (n *Named) resolveUnderlying() { // set underlying for all Named types in the chain for t := range seen { + // Careful, t.underlying has lock-free readers. Since we might be racing + // another call to resolveUnderlying, we have to avoid overwriting + // t.underlying. Otherwise, the race detector will be tripped. + if t.stateHas(underlying) { + continue + } t.underlying = u t.setState(underlying) }