aboutsummaryrefslogtreecommitdiff
path: root/src/context
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2016-04-10 15:45:34 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2016-04-11 01:52:10 +0000
commitbd7249766617fda12d112c3ad3ae2857ff97c71e (patch)
tree101e2ed0b9214c76ccfc3991f0ebf2b5c15a3c1e /src/context
parente6a8daceb0b0df77f5d2ca34a73561375bb89c63 (diff)
downloadgo-bd7249766617fda12d112c3ad3ae2857ff97c71e.tar.gz
go-bd7249766617fda12d112c3ad3ae2857ff97c71e.zip
context: document that WithValue's key must be comparable
Also, check it and explode earlier, rather than cryptic failures later. Change-Id: I319a425f60e2bc9d005a187fbdbd153faa96411c Reviewed-on: https://go-review.googlesource.com/21799 Reviewed-by: Andrew Gerrand <adg@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
Diffstat (limited to 'src/context')
-rw-r--r--src/context/context.go8
-rw-r--r--src/context/context_test.go13
2 files changed, 20 insertions, 1 deletions
diff --git a/src/context/context.go b/src/context/context.go
index 21dc8676bf..c332e1f443 100644
--- a/src/context/context.go
+++ b/src/context/context.go
@@ -39,6 +39,7 @@ package context
import (
"errors"
"fmt"
+ "reflect"
"sync"
"time"
)
@@ -424,7 +425,12 @@ func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
//
// Use context Values only for request-scoped data that transits processes and
// APIs, not for passing optional parameters to functions.
-func WithValue(parent Context, key interface{}, val interface{}) Context {
+//
+// The provided key must be comparable.
+func WithValue(parent Context, key, val interface{}) Context {
+ if !reflect.TypeOf(key).Comparable() {
+ panic("key is not comparable")
+ }
return &valueCtx{parent, key, val}
}
diff --git a/src/context/context_test.go b/src/context/context_test.go
index 573470e084..0616704dd8 100644
--- a/src/context/context_test.go
+++ b/src/context/context_test.go
@@ -586,3 +586,16 @@ func TestCancelRemoves(t *testing.T) {
cancel()
checkChildren("after cancelling WithTimeout child", ctx, 0)
}
+
+func TestWithValueChecksKey(t *testing.T) {
+ panicVal := recoveredValue(func() { WithValue(Background(), []byte("foo"), "bar") })
+ if panicVal == nil {
+ t.Error("expected panic")
+ }
+}
+
+func recoveredValue(fn func()) (v interface{}) {
+ defer func() { v = recover() }()
+ fn()
+ return
+}