universeIota *Const
universeByte *Basic // uint8 alias, but has name "byte"
universeRune *Basic // int32 alias, but has name "rune"
+ universeAny *Named
universeError *Named
)
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 {
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")
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
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