mirror of
https://github.com/golang/go.git
synced 2024-09-29 22:37:06 +00:00
template: indirect or dereference function arguments if necessary to match the type of the formal.
Fixes #2235 R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/4967056
This commit is contained in:
parent
0783dd9027
commit
d45e808c91
@ -506,7 +506,18 @@ func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Valu
|
||||
s.errorf("invalid value; expected %s", typ)
|
||||
}
|
||||
if !value.Type().AssignableTo(typ) {
|
||||
s.errorf("wrong type for value; expected %s; got %s", typ, value.Type())
|
||||
// Does one dereference or indirection work? We could do more, as we
|
||||
// do with method receivers, but that gets messy and method receivers
|
||||
// are much more constrained, so it makes more sense there than here.
|
||||
// Besides, one is almost always all you need.
|
||||
switch {
|
||||
case value.Kind() == reflect.Ptr && value.Elem().Type().AssignableTo(typ):
|
||||
value = value.Elem()
|
||||
case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr():
|
||||
value = value.Addr()
|
||||
default:
|
||||
s.errorf("wrong type for value; expected %s; got %s", typ, value.Type())
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
@ -416,6 +416,11 @@ var execTests = []execTest{
|
||||
{"bug4", "{{if .Empty0}}non-nil{{else}}nil{{end}}", "nil", tVal, true},
|
||||
// Stringer.
|
||||
{"bug5", "{{.Str}}", "foozle", tVal, true},
|
||||
// Args need to be indirected and dereferenced sometimes.
|
||||
{"bug6a", "{{vfunc .V0 .V1}}", "vfunc", tVal, true},
|
||||
{"bug6b", "{{vfunc .V0 .V0}}", "vfunc", tVal, true},
|
||||
{"bug6c", "{{vfunc .V1 .V0}}", "vfunc", tVal, true},
|
||||
{"bug6d", "{{vfunc .V1 .V1}}", "vfunc", tVal, true},
|
||||
}
|
||||
|
||||
func zeroArgs() string {
|
||||
@ -441,12 +446,18 @@ func count(n int) chan string {
|
||||
return c
|
||||
}
|
||||
|
||||
// vfunc takes a *V and a V
|
||||
func vfunc(V, *V) string {
|
||||
return "vfunc"
|
||||
}
|
||||
|
||||
func testExecute(execTests []execTest, set *Set, t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
funcs := FuncMap{
|
||||
"count": count,
|
||||
"oneArg": oneArg,
|
||||
"typeOf": typeOf,
|
||||
"vfunc": vfunc,
|
||||
"zeroArgs": zeroArgs,
|
||||
}
|
||||
for _, test := range execTests {
|
||||
|
Loading…
Reference in New Issue
Block a user