aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2019-08-10 22:06:25 +0200
committerRon Evans <[email protected]>2019-08-20 10:20:09 +0200
commite356bad4d1aeb66f2932ad556abbe13cfa716433 (patch)
tree5e0bcc77efd369ed2fc9761ce8730a90e333fc90
parentc19c738f523be8665a0e84c7905a6e0600f56404 (diff)
downloadtinygo-e356bad4d1aeb66f2932ad556abbe13cfa716433.tar.gz
tinygo-e356bad4d1aeb66f2932ad556abbe13cfa716433.zip
reflect: implement t.Comparable()
This is necessary to support the context package, which is a dependency of a lot of packages.
-rw-r--r--src/reflect/type.go38
-rw-r--r--testdata/reflect.go3
-rw-r--r--testdata/reflect.txt36
3 files changed, 59 insertions, 18 deletions
diff --git a/src/reflect/type.go b/src/reflect/type.go
index d537f40e0..b5142ca63 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -398,6 +398,44 @@ func (t Type) AssignableTo(u Type) bool {
return false
}
+// Comparable returns whether values of this type can be compared to each other.
+func (t Type) Comparable() bool {
+ switch t.Kind() {
+ case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ return true
+ case Float32, Float64, Complex64, Complex128:
+ return true
+ case String:
+ return true
+ case UnsafePointer:
+ return true
+ case Chan:
+ return true
+ case Interface:
+ return true
+ case Ptr:
+ return true
+ case Slice:
+ return false
+ case Array:
+ return t.Elem().Comparable()
+ case Func:
+ return false
+ case Map:
+ return false
+ case Struct:
+ numField := t.NumField()
+ for i := 0; i < numField; i++ {
+ if !t.Field(i).Type.Comparable() {
+ return false
+ }
+ }
+ return true
+ default:
+ panic(TypeError{"Comparable"})
+ }
+}
+
// A StructField describes a single field in a struct.
type StructField struct {
// Name indicates the field name.
diff --git a/testdata/reflect.go b/testdata/reflect.go
index 8377f95c9..4fe8cbb33 100644
--- a/testdata/reflect.go
+++ b/testdata/reflect.go
@@ -268,6 +268,9 @@ func showValue(rv reflect.Value, indent string) {
if rv.CanSet() {
print(" settable=", rv.CanSet())
}
+ if !rt.Comparable() {
+ print(" comparable=false")
+ }
println()
switch rt.Kind() {
case reflect.Bool:
diff --git a/testdata/reflect.txt b/testdata/reflect.txt
index ab3232bef..8bb878773 100644
--- a/testdata/reflect.txt
+++ b/testdata/reflect.txt
@@ -90,7 +90,7 @@ reflect type: ptr
nil: false
reflect type: int settable=true
int: 0
-reflect type: slice
+reflect type: slice comparable=false
slice: uint8 3 3
pointer: true
nil: false
@@ -103,7 +103,7 @@ reflect type: slice
indexing: 2
reflect type: uint8 settable=true
uint: 3
-reflect type: slice
+reflect type: slice comparable=false
slice: uint8 2 5
pointer: true
nil: false
@@ -113,7 +113,7 @@ reflect type: slice
indexing: 1
reflect type: uint8 settable=true
uint: 0
-reflect type: slice
+reflect type: slice comparable=false
slice: int32 2 2
pointer: true
nil: false
@@ -123,7 +123,7 @@ reflect type: slice
indexing: 1
reflect type: int32 settable=true
int: 5
-reflect type: slice
+reflect type: slice comparable=false
slice: string 2 2
pointer: true
nil: false
@@ -141,15 +141,15 @@ reflect type: slice
string: Z 1
reflect type: uint8
uint: 90
-reflect type: slice
+reflect type: slice comparable=false
slice: uint8 0 0
pointer: false
nil: true
-reflect type: slice
+reflect type: slice comparable=false
slice: uint8 0 0
pointer: true
nil: false
-reflect type: slice
+reflect type: slice comparable=false
slice: float32 2 2
pointer: true
nil: false
@@ -159,7 +159,7 @@ reflect type: slice
indexing: 1
reflect type: float32 settable=true
float: +1.320000e+000
-reflect type: slice
+reflect type: slice comparable=false
slice: float64 2 2
pointer: true
nil: false
@@ -169,7 +169,7 @@ reflect type: slice
indexing: 1
reflect type: float64 settable=true
float: +1.640000e+000
-reflect type: slice
+reflect type: slice comparable=false
slice: complex64 2 2
pointer: true
nil: false
@@ -179,7 +179,7 @@ reflect type: slice
indexing: 1
reflect type: complex64 settable=true
complex: (+1.640000e+000+3.000000e-001i)
-reflect type: slice
+reflect type: slice comparable=false
slice: complex128 2 2
pointer: true
nil: false
@@ -189,7 +189,7 @@ reflect type: slice
indexing: 1
reflect type: complex128 settable=true
complex: (+1.128000e+000+4.000000e-001i)
-reflect type: slice
+reflect type: slice comparable=false
slice: uint8 3 3
pointer: true
nil: false
@@ -216,16 +216,16 @@ reflect type: array
uint: 3
reflect type: uint8
uint: 5
-reflect type: func
+reflect type: func comparable=false
func
nil: true
-reflect type: func
+reflect type: func comparable=false
func
nil: false
-reflect type: map
+reflect type: map comparable=false
map
nil: true
-reflect type: map
+reflect type: map comparable=false
map
nil: false
reflect type: struct
@@ -255,7 +255,7 @@ reflect type: struct
embedded: false
reflect type: int8
int: 123
-reflect type: struct
+reflect type: struct comparable=false
struct: 5
field: 0 n
tag: foo:"bar"
@@ -285,7 +285,7 @@ reflect type: struct
field: 3 buf
tag:
embedded: false
- reflect type: slice
+ reflect type: slice comparable=false
slice: uint8 2 2
pointer: true
nil: false
@@ -298,7 +298,7 @@ reflect type: struct
field: 4 Buf
tag:
embedded: false
- reflect type: slice
+ reflect type: slice comparable=false
slice: uint8 1 1
pointer: true
nil: false