]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: import universe changes from dev.go2go
authorRob Findley <rfindley@google.com>
Tue, 8 Dec 2020 16:53:26 +0000 (11:53 -0500)
committerRobert Findley <rfindley@google.com>
Tue, 8 Dec 2020 17:21:49 +0000 (17:21 +0000)
This is unmodified from the dev.go2go branch, except to remove the aType
embedding.

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

index ff5b89118ad9ef940ae1fbe1e00276190e6f0476..f2f444fd9d1dd9320f81990d1d73a1165122577f 100644 (file)
@@ -24,6 +24,7 @@ var (
        universeIota  *Const
        universeByte  *Basic // uint8 alias, but has name "byte"
        universeRune  *Basic // int32 alias, but has name "rune"
+       universeAny   *Named
        universeError *Named
 )
 
@@ -77,13 +78,24 @@ func defPredeclaredTypes() {
                def(NewTypeName(token.NoPos, nil, t.name, t))
        }
 
+       // any
+       // (Predeclared and entered into universe scope so we do all the
+       // usual checks; but removed again from scope later since it's
+       // only visible as constraint in a type parameter list.)
+       {
+               typ := &Named{underlying: &emptyInterface}
+               def(NewTypeName(token.NoPos, nil, "any", typ))
+       }
+
        // Error has a nil package in its qualified name since it is in no package
-       res := NewVar(token.NoPos, nil, "", Typ[String])
-       sig := &Signature{results: NewTuple(res)}
-       err := NewFunc(token.NoPos, nil, "Error", sig)
-       typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil).Complete()}
-       sig.recv = NewVar(token.NoPos, nil, "", typ)
-       def(NewTypeName(token.NoPos, nil, "error", typ))
+       {
+               res := NewVar(token.NoPos, nil, "", Typ[String])
+               sig := &Signature{results: NewTuple(res)}
+               err := NewFunc(token.NoPos, nil, "Error", sig)
+               typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil).Complete()}
+               sig.recv = NewVar(token.NoPos, nil, "", typ)
+               def(NewTypeName(token.NoPos, nil, "error", typ))
+       }
 }
 
 var predeclaredConsts = [...]struct {
@@ -188,6 +200,33 @@ func DefPredeclaredTestFuncs() {
        def(newBuiltin(_Trace))
 }
 
+func defPredeclaredComparable() {
+       // The "comparable" interface can be imagined as defined like
+       //
+       // type comparable interface {
+       //         == () untyped bool
+       //         != () untyped bool
+       // }
+       //
+       // == and != cannot be user-declared but we can declare
+       // a magic method == and check for its presence when needed.
+
+       // Define interface { == () }. We don't care about the signature
+       // for == so leave it empty except for the receiver, which is
+       // set up later to match the usual interface method assumptions.
+       sig := new(Signature)
+       eql := NewFunc(token.NoPos, nil, "==", sig)
+       iface := NewInterfaceType([]*Func{eql}, nil).Complete()
+
+       // set up the defined type for the interface
+       obj := NewTypeName(token.NoPos, nil, "comparable", nil)
+       named := NewNamed(obj, iface, nil)
+       obj.color_ = black
+       sig.recv = NewVar(token.NoPos, nil, "", named) // complete == signature
+
+       def(obj)
+}
+
 func init() {
        Universe = NewScope(nil, token.NoPos, token.NoPos, "universe")
        Unsafe = NewPackage("unsafe", "unsafe")
@@ -197,11 +236,16 @@ func init() {
        defPredeclaredConsts()
        defPredeclaredNil()
        defPredeclaredFuncs()
+       defPredeclaredComparable()
 
        universeIota = Universe.Lookup("iota").(*Const)
        universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic)
        universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic)
+       universeAny = Universe.Lookup("any").(*TypeName).typ.(*Named)
        universeError = Universe.Lookup("error").(*TypeName).typ.(*Named)
+
+       // "any" is only visible as constraint in a type parameter list
+       delete(Universe.elems, "any")
 }
 
 // Objects with names containing blanks are internal and not entered into
@@ -215,7 +259,7 @@ func def(obj Object) {
                return // nothing to do
        }
        // fix Obj link for named types
-       if typ, ok := obj.Type().(*Named); ok {
+       if typ := asNamed(obj.Type()); typ != nil {
                typ.obj = obj.(*TypeName)
        }
        // exported identifiers go into package unsafe