aboutsummaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorDavid Crawshaw <crawshaw@golang.org>2018-01-02 09:43:41 -0800
committerIan Lance Taylor <iant@golang.org>2019-09-28 00:19:19 +0000
commit2d1c0332598c77097d53a1c2d564b12dcd644810 (patch)
treec062862352a3486278483ff33a2087c26ae10219 /src/reflect
parent739bf6b929b66ac1715268e269da01c8199f034b (diff)
downloadgo-2d1c0332598c77097d53a1c2d564b12dcd644810.tar.gz
go-2d1c0332598c77097d53a1c2d564b12dcd644810.zip
reflect: let StructOf define unexported fields
This was missing from the original StructOf CL because I couldn't think of a use for it. Now I can: even with types used entirely by reflect, unexported fields can be set using UnsafeAddr. Change-Id: I5e7e3d81d16e8817cdd69d85796ce33930ef523b Reviewed-on: https://go-review.googlesource.com/c/go/+/85661 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/all_test.go23
-rw-r--r--src/reflect/type.go19
2 files changed, 19 insertions, 23 deletions
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index fbb6feb0d9..7c5dd59aa7 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -4733,17 +4733,14 @@ func TestStructOfExportRules(t *testing.T) {
mustPanic: true,
},
{
- field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
- mustPanic: true,
+ field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
},
{
- field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
- mustPanic: true,
+ field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
},
{
- field: StructField{Name: "S", Type: TypeOf(S1{})},
- mustPanic: false,
- exported: true,
+ field: StructField{Name: "S", Type: TypeOf(S1{})},
+ exported: true,
},
{
field: StructField{Name: "S", Type: TypeOf((*S1)(nil))},
@@ -4774,20 +4771,16 @@ func TestStructOfExportRules(t *testing.T) {
mustPanic: true,
},
{
- field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
- mustPanic: true, // TODO(sbinet): creating a name with a package path
+ field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
},
{
- field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
- mustPanic: true, // TODO(sbinet): creating a name with a package path
+ field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
},
{
- field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
- mustPanic: true, // TODO(sbinet): creating a name with a package path
+ field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
},
{
- field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
- mustPanic: true, // TODO(sbinet): creating a name with a package path
+ field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
},
{
field: StructField{Name: "", Type: TypeOf(ΦType{})},
diff --git a/src/reflect/type.go b/src/reflect/type.go
index 2cf912cf54..f1f8ba93a4 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -2731,15 +2731,18 @@ func StructOf(fields []StructField) Type {
}
func runtimeStructField(field StructField) structField {
- if field.PkgPath != "" {
- panic("reflect.StructOf: StructOf does not allow unexported fields")
+ if field.Anonymous && field.PkgPath != "" {
+ panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
}
- // Best-effort check for misuse.
- // Since PkgPath is empty, not much harm done if Unicode lowercase slips through.
- c := field.Name[0]
- if 'a' <= c && c <= 'z' || c == '_' {
- panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath")
+ exported := field.PkgPath == ""
+ if exported {
+ // Best-effort check for misuse.
+ // Since this field will be treated as exported, not much harm done if Unicode lowercase slips through.
+ c := field.Name[0]
+ if 'a' <= c && c <= 'z' || c == '_' {
+ panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath")
+ }
}
offsetEmbed := uintptr(0)
@@ -2749,7 +2752,7 @@ func runtimeStructField(field StructField) structField {
resolveReflectType(field.Type.common()) // install in runtime
return structField{
- name: newName(field.Name, string(field.Tag), true),
+ name: newName(field.Name, string(field.Tag), exported),
typ: field.Type.common(),
offsetEmbed: offsetEmbed,
}