]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: use scope numbers to identify local types
authorRob Findley <rfindley@google.com>
Fri, 16 Jul 2021 18:20:18 +0000 (14:20 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 19 Jul 2021 15:49:47 +0000 (15:49 +0000)
This is a port of CL 333192 to go/types.

Change-Id: I12fd6b682d40c4d30b9ac0e87c463843cf5030d2
Reviewed-on: https://go-review.googlesource.com/c/go/+/335114
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/instance.go
src/go/types/scope.go
src/go/types/sizeof_test.go
src/go/types/subst.go
src/go/types/typestring.go
src/go/types/universe.go

index c57a947060107b800549a39238d9bba2a38c7cba..99771104bf814f8daa1395e998b4e06ab98f959e 100644 (file)
@@ -16,7 +16,7 @@ type instance struct {
        base    *Named      // parameterized type to be instantiated
        targs   []Type      // type arguments
        poslist []token.Pos // position of each targ; for error reporting only
-       value   Type        // base(targs...) after instantiation or Typ[Invalid]; nil if not yet set
+       value   Type        // base[targs...] after instantiation or Typ[Invalid]; nil if not yet set
 }
 
 // expand returns the instantiated (= expanded) type of t.
index fa6e0ecb8ff041d179ad5d472cc382376d2689e4..010727eb722a7bf81756e9ff17aa8e02a949f07b 100644 (file)
@@ -23,6 +23,7 @@ import (
 type Scope struct {
        parent   *Scope
        children []*Scope
+       number   int               // parent.children[number-1] is this scope; 0 if there is no parent
        elems    map[string]Object // lazily allocated
        pos, end token.Pos         // scope extent; may be invalid
        comment  string            // for debugging only
@@ -32,10 +33,11 @@ type Scope struct {
 // NewScope returns a new, empty scope contained in the given parent
 // scope, if any. The comment is for debugging only.
 func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope {
-       s := &Scope{parent, nil, nil, pos, end, comment, false}
+       s := &Scope{parent, nil, 0, nil, pos, end, comment, false}
        // don't add children to Universe scope!
        if parent != nil && parent != Universe {
                parent.children = append(parent.children, s)
+               s.number = len(parent.children)
        }
        return s
 }
index 8f5f42b4150409cc8dd370802b4547ce00c314ad..d03e1ea0cb39456b5d9bf2918eb4ac6ad0e635c9 100644 (file)
@@ -46,7 +46,7 @@ func TestSizeof(t *testing.T) {
                {Nil{}, 40, 72},
 
                // Misc
-               {Scope{}, 40, 80},
+               {Scope{}, 44, 88},
                {Package{}, 40, 80},
                {TypeSet{}, 20, 40},
        }
index d8388a948b88c5845ab8f632ddcc3081c8356838..4809b8c47a3f0c0e41de28acf3ee339f775755b6 100644 (file)
@@ -430,8 +430,6 @@ func (subst *subster) typ(typ Type) Type {
 
 var instanceHashing = 0
 
-// TODO(gri) Eventually, this should be more sophisticated.
-//           It won't work correctly for locally declared types.
 func instantiatedHash(typ *Named, targs []Type) string {
        assert(instanceHashing == 0)
        instanceHashing++
index f348d185c55adb5e6cbfb939877984a9b84bec72..4e73030613c763151967dfac9d6cfb3a3d9cd503 100644 (file)
@@ -358,22 +358,27 @@ func writeTypeName(buf *bytes.Buffer, obj *TypeName, qf Qualifier) {
        buf.WriteString(obj.name)
 
        if instanceHashing != 0 {
-               // For local defined types, use the (original!) TypeName's position
-               // to disambiguate. This is overkill, and could probably instead
-               // just be the pointer value (if we assume a non-moving GC) or
-               // a unique ID (like cmd/compile uses). But this works for now,
-               // and is convenient for debugging.
-
-               // TODO(mdempsky): I still don't fully understand why typ.orig.orig
-               // can differ from typ.orig, or whether looping more than twice is
-               // ever necessary.
+               // For local defined types, use the (original!) TypeName's scope
+               // numbers to disambiguate.
                typ := obj.typ.(*Named)
+               // TODO(gri) Figure out why typ.orig != typ.orig.orig sometimes
+               //           and whether the loop can iterate more than twice.
+               //           (It seems somehow connected to instance types.)
                for typ.orig != typ {
                        typ = typ.orig
                }
-               if orig := typ.obj; orig.pkg != nil && orig.parent != orig.pkg.scope {
-                       fmt.Fprintf(buf, "@%q", orig.pos)
-               }
+               writeScopeNumbers(buf, typ.obj.parent)
+       }
+}
+
+// writeScopeNumbers writes the number sequence for this scope to buf
+// in the form ".i.j.k" where i, j, k, etc. stand for scope numbers.
+// If a scope is nil or has no parent (such as a package scope), nothing
+// is written.
+func writeScopeNumbers(buf *bytes.Buffer, s *Scope) {
+       if s != nil && s.number > 0 {
+               writeScopeNumbers(buf, s.parent)
+               fmt.Fprintf(buf, ".%d", s.number)
        }
 }
 
index 540b0ac1189eb8dde607c0f8ba13bb87c1c72b3e..7c1e29b856cf5801a241caf5f3dcc36a3416f3b6 100644 (file)
@@ -87,21 +87,25 @@ func defPredeclaredTypes() {
 
        // type error interface{ Error() string }
        {
+               obj := NewTypeName(token.NoPos, nil, "error", nil)
+               obj.setColor(black)
                res := NewVar(token.NoPos, nil, "", Typ[String])
                sig := NewSignature(nil, nil, NewTuple(res), false)
                err := NewFunc(token.NoPos, nil, "Error", sig)
-               typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil)}
+               typ := NewNamed(obj, NewInterfaceType([]*Func{err}, nil), nil)
                sig.recv = NewVar(token.NoPos, nil, "", typ)
-               def(NewTypeName(token.NoPos, nil, "error", typ))
+               def(obj)
        }
 
        // type comparable interface{ ==() }
        {
+               obj := NewTypeName(token.NoPos, nil, "comparable", nil)
+               obj.setColor(black)
                sig := NewSignature(nil, nil, nil, false)
                eql := NewFunc(token.NoPos, nil, "==", sig)
-               typ := &Named{underlying: NewInterfaceType([]*Func{eql}, nil)}
+               typ := NewNamed(obj, NewInterfaceType([]*Func{eql}, nil), nil)
                sig.recv = NewVar(token.NoPos, nil, "", typ)
-               def(NewTypeName(token.NoPos, nil, "comparable", typ))
+               def(obj)
        }
 }