compiler, reflect: add support for named types

This commit is contained in:
Damian Gryski
2023-02-28 16:09:00 -08:00
committed by Damian Gryski
parent 45f119de34
commit 7654d86d2c
4 changed files with 43 additions and 5 deletions
+25 -2
View File
@@ -46,6 +46,12 @@
// - signature types (this is missing input and output parameters):
// meta uint8
// ptrTo *typeStruct
// - named types
// meta uint8
// ptrTo *typeStruct
// elem *typeStruct // underlying type
// nlem uintptr // length of name
// name [1]byte // actual name; length nlem
//
// The type struct is essentially a union of all the above types. Which it is,
// can be determined by looking at the meta byte.
@@ -417,6 +423,14 @@ type mapType struct {
key *rawType
}
type namedType struct {
rawType
ptrTo *rawType
elem *rawType
nlen uintptr
name [1]byte
}
// Type for struct types. The numField value is intentionally put before ptrTo
// for better struct packing on 32-bit and 64-bit architectures. On these
// architectures, the ptrTo field still has the same offset as in all the other
@@ -439,12 +453,16 @@ type structField struct {
// Equivalent to (go/types.Type).Underlying(): if this is a named type return
// the underlying type, else just return the type itself.
func (t *rawType) underlying() *rawType {
if t.meta&flagNamed != 0 {
if t.isNamed() {
return (*elemType)(unsafe.Pointer(t)).elem
}
return t
}
func (t *rawType) isNamed() bool {
return t.meta&flagNamed != 0
}
func TypeOf(i interface{}) Type {
return ValueOf(i).typecode
}
@@ -842,7 +860,12 @@ func (t *rawType) NumMethod() int {
}
func (t *rawType) Name() string {
panic("unimplemented: (reflect.Type).Name()")
if t.isNamed() {
ntype := (*namedType)(unsafe.Pointer(t))
return unsafe.String(&ntype.name[0], ntype.nlen)
}
return t.Kind().String()
}
func (t *rawType) Key() Type {
+10
View File
@@ -213,6 +213,16 @@ func TestBytes(t *testing.T) {
}
}
func TestNamedTypes(t *testing.T) {
type namedString string
named := namedString("foo")
if got, want := TypeOf(named).Name(), "namedString"; got != want {
t.Errorf("TypeOf.Name()=%v, want %v", got, want)
}
}
func equal[T comparable](a, b []T) bool {
if len(a) != len(b) {
return false