From 9f89972666e122c09bfe58aba4187ee5b3ee8332 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 3 May 2011 11:08:57 -0400 Subject: [release-branch.r57] reflect: allow unexported key in Value.MapIndex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ««« CL 4444087 / 9abf81a9df90 reflect: allow unexported key in Value.MapIndex Fixes #1748. R=golang-dev, r CC=golang-dev https://golang.org/cl/4444087 »»» R=r, r2 CC=golang-dev https://golang.org/cl/4433099 --- src/pkg/reflect/all_test.go | 22 +++++++++++++++++++++- src/pkg/reflect/value.go | 9 +++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go index 5bf65333c9..dee3f4915b 100644 --- a/src/pkg/reflect/all_test.go +++ b/src/pkg/reflect/all_test.go @@ -182,7 +182,9 @@ var valueTests = []pair{ }), "struct { c chan *int32; d float32 }{chan *int32, 0}", }, - {new(struct{ c func(chan *integer, *int8) }), + {new(struct { + c func(chan *integer, *int8) + }), "struct { c func(chan *reflect_test.integer, *int8) }{func(chan *reflect_test.integer, *int8)(0)}", }, {new(struct { @@ -732,6 +734,24 @@ func TestDeepEqualComplexStructInequality(t *testing.T) { } } +type UnexpT struct { + m map[int]int +} + +func TestDeepEqualUnexportedMap(t *testing.T) { + // Check that DeepEqual can look at unexported fields. + x1 := UnexpT{map[int]int{1: 2}} + x2 := UnexpT{map[int]int{1: 2}} + if !DeepEqual(&x1, &x2) { + t.Error("DeepEqual(x1, x2) = false, want true") + } + + y1 := UnexpT{map[int]int{2: 3}} + if DeepEqual(&x1, &y1) { + t.Error("DeepEqual(x1, y1) = true, want false") + } +} + func check2ndField(x interface{}, offs uintptr, t *testing.T) { s := ValueOf(x) diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go index 6dffb07833..2c2158a3cd 100644 --- a/src/pkg/reflect/value.go +++ b/src/pkg/reflect/value.go @@ -958,14 +958,19 @@ func (v Value) MapIndex(key Value) Value { iv.mustBe(Map) typ := iv.typ.toType() + // Do not require ikey to be exported, so that DeepEqual + // and other programs can use all the keys returned by + // MapKeys as arguments to MapIndex. If either the map + // or the key is unexported, though, the result will be + // considered unexported. + ikey := key.internal() - ikey.mustBeExported() ikey = convertForAssignment("reflect.Value.MapIndex", nil, typ.Key(), ikey) if iv.word == 0 { return Value{} } - flag := iv.flag & flagRO + flag := (iv.flag | ikey.flag) & flagRO elemType := typ.Elem() elemWord, ok := mapaccess(iv.word, ikey.word) if !ok { -- cgit v1.2.3-54-g00ecf