aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Crawshaw <crawshaw@golang.org>2016-11-04 18:22:06 -0400
committerRuss Cox <rsc@golang.org>2016-11-10 14:06:23 +0000
commit8d0c105407d235c85a163c0cda5bda86e5219c36 (patch)
treee56981d92136ab31896f529409d679cc59b8a745
parent9e2c3f4c7e78b01d635e16287789913d02807569 (diff)
downloadgo-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.go12
-rw-r--r--src/reflect/export_test.go4
-rw-r--r--src/reflect/type.go10
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
}