}
}
-// formalType replaces byte and rune aliases with real types.
+// formalType replaces predeclared aliases with real types.
// They've been separate internally to make error messages
// better, but we have to merge them in the reflect tables.
func formalType(t *types.Type) *types.Type {
- if t == types.ByteType || t == types.RuneType {
+ switch t {
+ case types.AnyType, types.ByteType, types.RuneType:
return types.Types[t.Kind()]
}
return t
return
}
- if t == ByteType || t == RuneType {
- // in %-T mode collapse rune and byte with their originals.
+ if t == AnyType || t == ByteType || t == RuneType {
+ // in %-T mode collapse predeclared aliases with their originals.
switch mode {
case fmtTypeIDName, fmtTypeID:
t = Types[t.Kind()]
return (t1 == Types[TUINT8] || t1 == ByteType) && (t2 == Types[TUINT8] || t2 == ByteType)
case TINT32:
return (t1 == Types[TINT32] || t1 == RuneType) && (t2 == Types[TINT32] || t2 == RuneType)
+ case TINTER:
+ return (t1 == Types[TINTER] || t1 == AnyType) && (t2 == Types[TINTER] || t2 == AnyType)
default:
return false
}
// It also stores pointers to several special types:
// - Types[TANY] is the placeholder "any" type recognized by SubstArgTypes.
// - Types[TBLANK] represents the blank variable's type.
+// - Types[TINTER] is the canonical "interface{}" type.
// - Types[TNIL] represents the predeclared "nil" value's type.
// - Types[TUNSAFEPTR] is package unsafe's Pointer type.
var Types [NTYPE]*Type
var (
- // Predeclared alias types. Kept separate for better error messages.
+ // Predeclared alias types. These are actually created as distinct
+ // defined types for better error messages, but are then specially
+ // treated as identical to their respective underlying types.
+ AnyType *Type
ByteType *Type
RuneType *Type
ErrorType *Type
// Predeclared comparable interface type.
ComparableType *Type
- // Predeclared any interface type.
- AnyType *Type
// Types to represent untyped string and boolean constants.
UntypedString = newType(TSTRING)
if (t == Types[RuneType.kind] || t == RuneType) && (x == Types[RuneType.kind] || x == RuneType) {
return CMPeq
}
+
+ case TINTER:
+ if (t == Types[AnyType.kind] || t == AnyType) && (x == Types[AnyType.kind] || x == AnyType) {
+ return CMPeq
+ }
}
}
Types[TANY] = newType(TANY)
Types[TINTER] = NewInterface(LocalPkg, nil, false)
+ CheckSize(Types[TINTER])
defBasic := func(kind Kind, pkg *Pkg, name string) *Type {
typ := newType(kind)
ResumeCheckSize()
// any type (interface)
- if base.Flag.G > 0 {
- DeferCheckSize()
- AnyType = defBasic(TFORW, BuiltinPkg, "any")
- AnyType.SetUnderlying(NewInterface(NoPkg, []*Field{}, false))
- ResumeCheckSize()
+ DeferCheckSize()
+ AnyType = defBasic(TFORW, BuiltinPkg, "any")
+ AnyType.SetUnderlying(NewInterface(NoPkg, []*Field{}, false))
+ ResumeCheckSize()
+
+ if base.Flag.G == 0 {
+ ComparableType.Sym().Def = nil
+ AnyType.Sym().Def = nil
}
Types[TUNSAFEPTR] = defBasic(TUNSAFEPTR, UnsafePkg, "Pointer")
--- /dev/null
+// run
+
+// Copyright 2021 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 main
+
+import "fmt"
+
+var x any
+var y interface{}
+
+var _ = &x == &y // assert x and y have identical types
+
+func main() {
+ fmt.Printf("%T\n%T\n", &x, &y)
+}
--- /dev/null
+*interface {}
+*interface {}