From: Emmanuel Odeke Date: Mon, 22 May 2017 21:17:38 +0000 (-0600) Subject: text/template: support indexing into *int* maps X-Git-Tag: go1.10beta1~1634 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=590c5b08070dfb2ddeb2b2583acc3a2b0fcb03bb;p=gostls13.git text/template: support indexing into *int* maps Ensure that we can index maps whose key types are: * int * uint * int32 * uint32 * int64 * uint64 * uintptr Fixes #20439 Change-Id: I8fa96b14073c8af72786482ff4ffc3508064ea86 Reviewed-on: https://go-review.googlesource.com/43850 Run-TryBot: Emmanuel Odeke Run-TryBot: Rob Pike TryBot-Result: Gobot Gobot Reviewed-by: Rob Pike Reviewed-by: Brad Fitzpatrick --- diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go index 9f7e637c19..d0cda6bd62 100644 --- a/src/text/template/exec_test.go +++ b/src/text/template/exec_test.go @@ -44,6 +44,12 @@ type T struct { MSIEmpty map[string]int MXI map[interface{}]int MII map[int]int + MI32S map[int32]string + MI64S map[int64]string + MUI32S map[uint32]string + MUI64S map[uint64]string + MI8S map[int8]string + MUI8S map[uint8]string SMSI []map[string]int // Empty interfaces; used to see if we can dig inside one. Empty0 interface{} // nil @@ -124,6 +130,12 @@ var tVal = &T{ MSIone: map[string]int{"one": 1}, MXI: map[interface{}]int{"one": 1}, MII: map[int]int{1: 1}, + MI32S: map[int32]string{1: "one", 2: "two"}, + MI64S: map[int64]string{2: "i642", 3: "i643"}, + MUI32S: map[uint32]string{2: "u322", 3: "u323"}, + MUI64S: map[uint64]string{2: "ui642", 3: "ui643"}, + MI8S: map[int8]string{2: "i82", 3: "i83"}, + MUI8S: map[uint8]string{2: "u82", 3: "u83"}, SMSI: []map[string]int{ {"one": 1, "two": 2}, {"eleven": 11, "twelve": 12}, @@ -448,6 +460,11 @@ var execTests = []execTest{ {"map[WRONG]", "{{index .MSI 10}}", "", tVal, false}, {"double index", "{{index .SMSI 1 `eleven`}}", "11", tVal, true}, {"nil[1]", "{{index nil 1}}", "", tVal, false}, + {"map MI64S", "{{index .MI64S 2}}", "i642", tVal, true}, + {"map MI32S", "{{index .MI32S 2}}", "two", tVal, true}, + {"map MUI64S", "{{index .MUI64S 3}}", "ui643", tVal, true}, + {"map MI8S", "{{index .MI8S 3}}", "i83", tVal, true}, + {"map MUI8S", "{{index .MUI8S 2}}", "u82", tVal, true}, // Len. {"slice", "{{len .SI}}", "3", tVal, true}, diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go index 9107431037..abddfa1141 100644 --- a/src/text/template/funcs.go +++ b/src/text/template/funcs.go @@ -139,10 +139,24 @@ func prepareArg(value reflect.Value, argType reflect.Type) (reflect.Value, error } value = reflect.Zero(argType) } - if !value.Type().AssignableTo(argType) { - return reflect.Value{}, fmt.Errorf("value has type %s; should be %s", value.Type(), argType) + if value.Type().AssignableTo(argType) { + return value, nil } - return value, nil + if intLike(value.Kind()) && intLike(argType.Kind()) && value.Type().ConvertibleTo(argType) { + value = value.Convert(argType) + return value, nil + } + return reflect.Value{}, fmt.Errorf("value has type %s; should be %s", value.Type(), argType) +} + +func intLike(typ reflect.Kind) bool { + switch typ { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return true + } + return false } // Indexing.