From ebf182c82de21858a1a167cc8d252ae85de806a7 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Wed, 27 Jul 2022 23:19:40 -0700 Subject: [PATCH] reflect: avoid TypeOf in init Calling TypeOf to initialize variables forces any import of "reflect" to link in the declared types of "reflect" even if they are unused. TypeOf operates on Type and which will pull in all transitive dependencies of Type, which includes Value as well. Avoid this problem by declaring a rtypeOf function that directly extracts the *rtype from an interface value without going through Type as an intermediate type. For a program that blank imports "reflect", this reduces the binary size by ~34 KiB. Updates #54097 Change-Id: I8dc7d8da8fedc48cc0dd842b69f510d17144827e Reviewed-on: https://go-review.googlesource.com/c/go/+/419757 Run-TryBot: Joseph Tsai Reviewed-by: Bryan Mills Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot --- src/reflect/type.go | 6 ++++++ src/reflect/value.go | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/reflect/type.go b/src/reflect/type.go index 75994c97a9..cb657905d0 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -1433,6 +1433,12 @@ func TypeOf(i any) Type { return toType(eface.typ) } +// rtypeOf directly extracts the *rtype of the provided value. +func rtypeOf(i any) *rtype { + eface := *(*emptyInterface)(unsafe.Pointer(&i)) + return eface.typ +} + // ptrMap is the cache for PointerTo. var ptrMap sync.Map // map[*rtype]*ptrType diff --git a/src/reflect/value.go b/src/reflect/value.go index 969e57cf83..d8479c64ef 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -290,7 +290,7 @@ func (v Value) panicNotBool() { v.mustBe(Bool) } -var bytesType = TypeOf(([]byte)(nil)).(*rtype) +var bytesType = rtypeOf(([]byte)(nil)) // Bytes returns v's underlying value. // It panics if v's underlying value is not a slice of bytes or @@ -1381,7 +1381,7 @@ func (v Value) Float() float64 { panic(&ValueError{"reflect.Value.Float", v.kind()}) } -var uint8Type = TypeOf(uint8(0)).(*rtype) +var uint8Type = rtypeOf(uint8(0)) // Index returns v's i'th element. // It panics if v's Kind is not Array, Slice, or String or i is out of range. @@ -1640,7 +1640,7 @@ func (v Value) lenNonSlice() int { panic(&ValueError{"reflect.Value.Len", v.kind()}) } -var stringType = TypeOf("").(*rtype) +var stringType = rtypeOf("") // MapIndex returns the value associated with key in the map v. // It panics if v's Kind is not Map. -- 2.50.0