]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: review of sanitize.go
authorRobert Griesemer <gri@golang.org>
Sat, 20 Feb 2021 04:06:24 +0000 (20:06 -0800)
committerRobert Griesemer <gri@golang.org>
Tue, 23 Feb 2021 04:51:48 +0000 (04:51 +0000)
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>
src/cmd/compile/internal/types2/sanitize.go

index bac569416b4cb2ca8d99f80a196485bba033d130..cd1719c8c0f915d6b91d426121810b286addd88b 100644 (file)
@@ -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
+               }
        }
 }