mirror of
https://github.com/golang/go
synced 2024-11-19 03:04:42 -07:00
cmd/compile/internal/types2: review of sanitize.go
Remove the "// UNREVIEWED" marker and add guards (as in go/types) to prevent data races. To see the added guards, see compare patch sets 3 and 4. The equivalent changes for go/types were done in https://golang.org/cl/294411. Change-Id: Ibef07eaae400bd32bff32b102cc743580290d135 Reviewed-on: https://go-review.googlesource.com/c/go/+/294510 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
975ba6e2b2
commit
6a40dd05d8
@ -1,10 +1,16 @@
|
||||
// UNREVIEWED
|
||||
// Copyright 2020 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 types2
|
||||
|
||||
// sanitizeInfo walks the types contained in info to ensure that all instances
|
||||
// are expanded.
|
||||
//
|
||||
// This includes some objects that may be shared across concurrent
|
||||
// type-checking passes (such as those in the universe scope), so we are
|
||||
// careful here not to write types that are already sanitized. This avoids a
|
||||
// data race as any shared types should already be sanitized.
|
||||
func sanitizeInfo(info *Info) {
|
||||
var s sanitizer = make(map[Type]Type)
|
||||
|
||||
@ -12,27 +18,42 @@ func sanitizeInfo(info *Info) {
|
||||
// If modified, they must be assigned back.
|
||||
|
||||
for e, tv := range info.Types {
|
||||
tv.Type = s.typ(tv.Type)
|
||||
info.Types[e] = tv
|
||||
if typ := s.typ(tv.Type); typ != tv.Type {
|
||||
tv.Type = typ
|
||||
info.Types[e] = tv
|
||||
}
|
||||
}
|
||||
|
||||
for e, inf := range info.Inferred {
|
||||
changed := false
|
||||
for i, targ := range inf.Targs {
|
||||
inf.Targs[i] = s.typ(targ)
|
||||
if typ := s.typ(targ); typ != targ {
|
||||
inf.Targs[i] = typ
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if typ := s.typ(inf.Sig); typ != inf.Sig {
|
||||
inf.Sig = typ.(*Signature)
|
||||
changed = true
|
||||
}
|
||||
if changed {
|
||||
info.Inferred[e] = inf
|
||||
}
|
||||
inf.Sig = s.typ(inf.Sig).(*Signature)
|
||||
info.Inferred[e] = inf
|
||||
}
|
||||
|
||||
for _, obj := range info.Defs {
|
||||
if obj != nil {
|
||||
obj.setType(s.typ(obj.Type()))
|
||||
if typ := s.typ(obj.Type()); typ != obj.Type() {
|
||||
obj.setType(typ)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, obj := range info.Uses {
|
||||
if obj != nil {
|
||||
obj.setType(s.typ(obj.Type()))
|
||||
if typ := s.typ(obj.Type()); typ != obj.Type() {
|
||||
obj.setType(typ)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,16 +77,22 @@ func (s sanitizer) typ(typ Type) Type {
|
||||
// nothing to do
|
||||
|
||||
case *Array:
|
||||
t.elem = s.typ(t.elem)
|
||||
if elem := s.typ(t.elem); elem != t.elem {
|
||||
t.elem = elem
|
||||
}
|
||||
|
||||
case *Slice:
|
||||
t.elem = s.typ(t.elem)
|
||||
if elem := s.typ(t.elem); elem != t.elem {
|
||||
t.elem = elem
|
||||
}
|
||||
|
||||
case *Struct:
|
||||
s.varList(t.fields)
|
||||
|
||||
case *Pointer:
|
||||
t.base = s.typ(t.base)
|
||||
if base := s.typ(t.base); base != t.base {
|
||||
t.base = base
|
||||
}
|
||||
|
||||
case *Tuple:
|
||||
s.tuple(t)
|
||||
@ -86,27 +113,39 @@ func (s sanitizer) typ(typ Type) Type {
|
||||
s.typ(t.allTypes)
|
||||
|
||||
case *Map:
|
||||
t.key = s.typ(t.key)
|
||||
t.elem = s.typ(t.elem)
|
||||
if key := s.typ(t.key); key != t.key {
|
||||
t.key = key
|
||||
}
|
||||
if elem := s.typ(t.elem); elem != t.elem {
|
||||
t.elem = elem
|
||||
}
|
||||
|
||||
case *Chan:
|
||||
t.elem = s.typ(t.elem)
|
||||
if elem := s.typ(t.elem); elem != t.elem {
|
||||
t.elem = elem
|
||||
}
|
||||
|
||||
case *Named:
|
||||
t.orig = s.typ(t.orig)
|
||||
t.underlying = s.typ(t.underlying)
|
||||
if orig := s.typ(t.orig); orig != t.orig {
|
||||
t.orig = orig
|
||||
}
|
||||
if under := s.typ(t.underlying); under != t.underlying {
|
||||
t.underlying = under
|
||||
}
|
||||
s.typeList(t.targs)
|
||||
s.funcList(t.methods)
|
||||
|
||||
case *TypeParam:
|
||||
t.bound = s.typ(t.bound)
|
||||
if bound := s.typ(t.bound); bound != t.bound {
|
||||
t.bound = bound
|
||||
}
|
||||
|
||||
case *instance:
|
||||
typ = t.expand()
|
||||
s[t] = typ
|
||||
|
||||
default:
|
||||
unimplemented()
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
return typ
|
||||
@ -114,7 +153,9 @@ func (s sanitizer) typ(typ Type) Type {
|
||||
|
||||
func (s sanitizer) var_(v *Var) {
|
||||
if v != nil {
|
||||
v.typ = s.typ(v.typ)
|
||||
if typ := s.typ(v.typ); typ != v.typ {
|
||||
v.typ = typ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +173,9 @@ func (s sanitizer) tuple(t *Tuple) {
|
||||
|
||||
func (s sanitizer) func_(f *Func) {
|
||||
if f != nil {
|
||||
f.typ = s.typ(f.typ)
|
||||
if typ := s.typ(f.typ); typ != f.typ {
|
||||
f.typ = typ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,6 +187,8 @@ func (s sanitizer) funcList(list []*Func) {
|
||||
|
||||
func (s sanitizer) typeList(list []Type) {
|
||||
for i, t := range list {
|
||||
list[i] = s.typ(t)
|
||||
if typ := s.typ(t); typ != t {
|
||||
list[i] = typ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user