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>
import (
"errors"
"fmt"
+ "reflect"
"sync"
"time"
)
//
// 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}
}
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
+}
"compress/gzip": {"L4", "compress/flate"},
"compress/lzw": {"L4"},
"compress/zlib": {"L4", "compress/flate"},
- "context": {"errors", "fmt", "sync", "time"},
+ "context": {"errors", "fmt", "reflect", "sync", "time"},
"database/sql": {"L4", "container/list", "database/sql/driver"},
"database/sql/driver": {"L4", "time"},
"debug/dwarf": {"L4"},