diff options
author | David Crawshaw <crawshaw@golang.org> | 2016-11-04 18:22:06 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2016-11-10 14:06:23 +0000 |
commit | 8d0c105407d235c85a163c0cda5bda86e5219c36 (patch) | |
tree | e56981d92136ab31896f529409d679cc59b8a745 | |
parent | 9e2c3f4c7e78b01d635e16287789913d02807569 (diff) | |
download | go-8d0c105407d235c85a163c0cda5bda86e5219c36.tar.gz go-8d0c105407d235c85a163c0cda5bda86e5219c36.zip |
reflect: unexported fields are tied to a package
An unexported field of a struct is not visible outside of the package
that defines it, so the package path is implicitly part of the
definition of any struct with an unexported field.
Change-Id: I17c6aac822bd0c24188ab8ba1cc406d6b5d82771
Reviewed-on: https://go-review.googlesource.com/32820
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
-rw-r--r-- | src/reflect/all_test.go | 12 | ||||
-rw-r--r-- | src/reflect/export_test.go | 4 | ||||
-rw-r--r-- | src/reflect/type.go | 10 |
3 files changed, 26 insertions, 0 deletions
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index c99ad79b64..4c11609218 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -5913,3 +5913,15 @@ func TestSwapper(t *testing.T) { } } } + +func TestInaccessibleField(t *testing.T) { + var b Buffer + var localBuffer struct { + buf []byte + } + lv := ValueOf(&localBuffer).Elem() + rv := ValueOf(b) + shouldPanic(func() { + lv.Set(rv) + }) +} diff --git a/src/reflect/export_test.go b/src/reflect/export_test.go index 2cc1530250..ffd1104487 100644 --- a/src/reflect/export_test.go +++ b/src/reflect/export_test.go @@ -113,3 +113,7 @@ func IsExported(t Type) bool { func ResolveReflectName(s string) { resolveReflectName(newName(s, "", "", false)) } + +type Buffer struct { + buf []byte +} diff --git a/src/reflect/type.go b/src/reflect/type.go index 66c27ebb93..e04eff7931 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -1680,6 +1680,7 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { if len(t.fields) != len(v.fields) { return false } + allExported := true for i := range t.fields { tf := &t.fields[i] vf := &v.fields[i] @@ -1695,6 +1696,15 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { if tf.offset != vf.offset { return false } + allExported = allExported && tf.name.isExported() + } + if !allExported && t.pkgPath.name() != v.pkgPath.name() { + // An unexported field of a struct is not + // visible outside of the package that defines + // it, so the package path is implicitly part + // of the definition of any struct with an + // unexported field. + return false } return true } |