aboutsummaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-07-22 12:50:30 -0700
committerMatthew Dempsky <mdempsky@google.com>2021-07-22 12:50:31 -0700
commita27e325c59691fba23c094ab07fd5735737ac8ba (patch)
tree2dc7632b501359c291d95d7d15cd37f347727cd8 /src/reflect
parent5cb84f0604797df436d8fde548d4f797b3a6c245 (diff)
parent798ec73519a7226d6d436e42498a54aed23b8468 (diff)
downloadgo-a27e325c59691fba23c094ab07fd5735737ac8ba.tar.gz
go-a27e325c59691fba23c094ab07fd5735737ac8ba.zip
[dev.typeparams] all: merge master (798ec73) into dev.typeparams
Merge List: + 2021-07-22 798ec73519 runtime: don't clear timerModifiedEarliest if adjustTimers is 0 + 2021-07-22 fdb45acd1f runtime: move mem profile sampling into m-acquired section + 2021-07-21 3e48c0381f reflect: add missing copyright header + 2021-07-21 48c88f1b1b reflect: add Value.CanConvert + 2021-07-20 9e26569293 cmd/go: don't add C compiler ID to hash for standard library + 2021-07-20 d568e6e075 runtime/debug: skip TestPanicOnFault on netbsd/arm Change-Id: I87e1cd4614bb3b00807f18dfdd02664dcaecaebd
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/all_test.go9
-rw-r--r--src/reflect/value.go20
-rw-r--r--src/reflect/visiblefields.go4
-rw-r--r--src/reflect/visiblefields_test.go4
4 files changed, 37 insertions, 0 deletions
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index e3faa31c1f..5e5e4c1e60 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -4305,6 +4305,9 @@ func TestConvert(t *testing.T) {
// vout1 represents the in value converted to the in type.
v1 := tt.in
+ if !v1.CanConvert(t1) {
+ t.Errorf("ValueOf(%T(%[1]v)).CanConvert(%s) = false, want true", tt.in.Interface(), t1)
+ }
vout1 := v1.Convert(t1)
out1 := vout1.Interface()
if vout1.Type() != tt.in.Type() || !DeepEqual(out1, tt.in.Interface()) {
@@ -4312,6 +4315,9 @@ func TestConvert(t *testing.T) {
}
// vout2 represents the in value converted to the out type.
+ if !v1.CanConvert(t2) {
+ t.Errorf("ValueOf(%T(%[1]v)).CanConvert(%s) = false, want true", tt.in.Interface(), t2)
+ }
vout2 := v1.Convert(t2)
out2 := vout2.Interface()
if vout2.Type() != tt.out.Type() || !DeepEqual(out2, tt.out.Interface()) {
@@ -4372,6 +4378,9 @@ func TestConvertPanic(t *testing.T) {
if !v.Type().ConvertibleTo(pt) {
t.Errorf("[]byte should be convertible to *[8]byte")
}
+ if v.CanConvert(pt) {
+ t.Errorf("slice with length 4 should not be convertible to *[8]byte")
+ }
shouldPanic("reflect: cannot convert slice with length 4 to pointer to array with length 8", func() {
_ = v.Convert(pt)
})
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 7589966e22..b4b2d2e38b 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -2807,6 +2807,26 @@ func (v Value) Convert(t Type) Value {
return op(v, t)
}
+// CanConvert reports whether the value v can be converted to type t.
+// If v.CanConvert(t) returns true then v.Convert(t) will not panic.
+func (v Value) CanConvert(t Type) bool {
+ vt := v.Type()
+ if !vt.ConvertibleTo(t) {
+ return false
+ }
+ // Currently the only conversion that is OK in terms of type
+ // but that can panic depending on the value is converting
+ // from slice to pointer-to-array.
+ if vt.Kind() == Slice && t.Kind() == Ptr && t.Elem().Kind() == Array {
+ n := t.Elem().Len()
+ h := (*unsafeheader.Slice)(v.ptr)
+ if n > h.Len {
+ return false
+ }
+ }
+ return true
+}
+
// convertOp returns the function to convert a value of type src
// to a value of type dst. If the conversion is illegal, convertOp returns nil.
func convertOp(dst, src *rtype) func(Value, Type) Value {
diff --git a/src/reflect/visiblefields.go b/src/reflect/visiblefields.go
index c068979dcc..1a2b53570b 100644
--- a/src/reflect/visiblefields.go
+++ b/src/reflect/visiblefields.go
@@ -1,3 +1,7 @@
+// 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 reflect
// VisibleFields returns all the visible fields in t, which must be a
diff --git a/src/reflect/visiblefields_test.go b/src/reflect/visiblefields_test.go
index 2688b63091..915bbee867 100644
--- a/src/reflect/visiblefields_test.go
+++ b/src/reflect/visiblefields_test.go
@@ -1,3 +1,7 @@
+// 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 reflect_test
import (