]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile/internal/types2: use scope numbers to identify local...
authorRobert Griesemer <gri@golang.org>
Thu, 8 Jul 2021 04:38:49 +0000 (21:38 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 9 Jul 2021 17:36:57 +0000 (17:36 +0000)
Rather than using a local types' position information, use the type
name's scope numbers to uniquely identify the type from others with
the same name.

We use scope numbers rather than indices (with number-1 == index)
to preserve the invariant that the zero value for a scope is a ready
to use empty scope.

Using scope numbers turned out to be fairly simple after all and
provides a reasonably stable identification which will make debugging
simpler. A scope number series may be a bit longer than a unique ID for
each type name but local types should be reasonably rare.

Also did a minor cleanup in universe.go to ensure Named.orig is set up
correctly (there's still an open TODO but with a work-around).

Change-Id: I73935fa9bd960809fd5c95fe8b8a535c313cfc8f
Reviewed-on: https://go-review.googlesource.com/c/go/+/333192
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>

src/cmd/compile/internal/types2/instance.go
src/cmd/compile/internal/types2/scope.go
src/cmd/compile/internal/types2/sizeof_test.go
src/cmd/compile/internal/types2/subst.go
src/cmd/compile/internal/types2/typestring.go
src/cmd/compile/internal/types2/universe.go

index 9d6097e87421c38696f294ac7256c4dc8b569a6a..b133fd1e65df1e3c57c43b02f4bb3257309b994e 100644 (file)
@@ -16,7 +16,7 @@ type instance struct {
        base    *Named       // parameterized type to be instantiated
        targs   []Type       // type arguments
        poslist []syntax.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 2f1814a6319773d9dc345fa1f365c3e62106c784..095875d94b0d9ecec9d318d6456a0420abbd7442 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 syntax.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 syntax.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 0b1f7dacad38f4d2337ade421dbe4c0dd0dcd75d..a51d0c43d5aa9cdc92f267939acd23454d72ca22 100644 (file)
@@ -47,7 +47,7 @@ func TestSizeof(t *testing.T) {
                {Nil{}, 56, 88},
 
                // Misc
-               {Scope{}, 56, 96},
+               {Scope{}, 60, 104},
                {Package{}, 40, 80},
                {TypeSet{}, 20, 40},
        }
index 7b4796fa2ebada79ce51c6c5e4a23b06893d7873..59efe8a0459a1ea10aeb7959ab1b15cd82b20816 100644 (file)
@@ -422,8 +422,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 f63a23c98ce8772852883daf98a0ecaaf6ab2ab5..44099133a03dd3b41f27e87f7cfb87cfc66cb458 100644 (file)
@@ -363,22 +363,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 c9b53bac921ece7d9bb4079c12b7cb0749a61f04..d328b13a8e1b708a5ef9b868dee658e92c83b6be 100644 (file)
@@ -86,21 +86,25 @@ func defPredeclaredTypes() {
 
        // type error interface{ Error() string }
        {
+               obj := NewTypeName(nopos, nil, "error", nil)
+               obj.setColor(black)
                res := NewVar(nopos, nil, "", Typ[String])
                sig := NewSignature(nil, nil, NewTuple(res), false)
                err := NewFunc(nopos, nil, "Error", sig)
-               typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil)}
+               typ := NewNamed(obj, NewInterfaceType([]*Func{err}, nil), nil)
                sig.recv = NewVar(nopos, nil, "", typ)
-               def(NewTypeName(nopos, nil, "error", typ))
+               def(obj)
        }
 
        // type comparable interface{ ==() }
        {
+               obj := NewTypeName(nopos, nil, "comparable", nil)
+               obj.setColor(black)
                sig := NewSignature(nil, nil, nil, false)
                eql := NewFunc(nopos, nil, "==", sig)
-               typ := &Named{underlying: NewInterfaceType([]*Func{eql}, nil)}
+               typ := NewNamed(obj, NewInterfaceType([]*Func{eql}, nil), nil)
                sig.recv = NewVar(nopos, nil, "", typ)
-               def(NewTypeName(nopos, nil, "comparable", typ))
+               def(obj)
        }
 }