reflect: let reflect.Type be of interface type

This matches the main Go implementation and (among others) fixes a
compatibility issue with the encoding/json package. The encoding/json
package compares reflect.Type variables against nil, which does not work
as long as reflect.Type is of integer type.

This also adds a reflect.RawType() function (like reflect.Type()) that
makes it easier to avoid working with interfaces in the runtime package.
It is internal only, but exported to let the runtime package use it.

This change introduces a small code size increase when working with the
reflect package, but I've tried to keep it to a minimum. Most programs
that don't make extensive use of the reflect package (and don't use
package like fmt) should not be impacted by this.
This commit is contained in:
Ayke van Laethem
2021-01-22 17:19:42 +01:00
committed by Ron Evans
parent cffe424849
commit c849bccb83
6 changed files with 312 additions and 81 deletions
+7 -4
View File
@@ -31,18 +31,21 @@ func interfaceEqual(x, y interface{}) bool {
}
func reflectValueEqual(x, y reflect.Value) bool {
if x.Type() == 0 || y.Type() == 0 {
// Note: doing a x.Type() == y.Type() comparison would not work here as that
// would introduce an infinite recursion: comparing two reflect.Type values
// is done with this reflectValueEqual runtime call.
if x.RawType() == 0 || y.RawType() == 0 {
// One of them is nil.
return x.Type() == y.Type()
return x.RawType() == y.RawType()
}
if x.Type() != y.Type() {
if x.RawType() != y.RawType() {
// The type is not the same, which means the interfaces are definitely
// not the same.
return false
}
switch x.Type().Kind() {
switch x.RawType().Kind() {
case reflect.Bool:
return x.Bool() == y.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: