aboutsummaryrefslogtreecommitdiff
path: root/src/text
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-10-01 12:32:41 -0700
committerIan Lance Taylor <iant@golang.org>2021-10-01 23:51:16 +0000
commitc129af90eb20a5723fc7ed19b19afe054036fe71 (patch)
tree0090f887d63d7f73dfa14e7a8e6048c0cc8602b0 /src/text
parent0d65c272c9e494cbb604f2bee99d434b8cde46ff (diff)
downloadgo-c129af90eb20a5723fc7ed19b19afe054036fe71.tar.xz
text/template: undo reflect.Value wrapping for short-circuit and/or
For #31103 Change-Id: I9c0aa64f95f564de31a4c178e3930584d41316bb Reviewed-on: https://go-review.googlesource.com/c/go/+/353610 Trust: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/text')
-rw-r--r--src/text/template/exec.go16
-rw-r--r--src/text/template/exec_test.go1
2 files changed, 11 insertions, 6 deletions
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
index fce3b0abbf..9a4c9e29dd 100644
--- a/src/text/template/exec.go
+++ b/src/text/template/exec.go
@@ -714,6 +714,13 @@ func (s *state) evalCall(dot, fun reflect.Value, isBuiltin bool, node parse.Node
s.errorf("can't call method/function %q with %d results", name, typ.NumOut())
}
+ unwrap := func(v reflect.Value) reflect.Value {
+ if v.Type() == reflectValueType {
+ v = v.Interface().(reflect.Value)
+ }
+ return v
+ }
+
// Special case for builtin and/or, which short-circuit.
if isBuiltin && (name == "and" || name == "or") {
argType := typ.In(0)
@@ -721,13 +728,13 @@ func (s *state) evalCall(dot, fun reflect.Value, isBuiltin bool, node parse.Node
for _, arg := range args {
v = s.evalArg(dot, argType, arg).Interface().(reflect.Value)
if truth(v) == (name == "or") {
- return v
+ return unwrap(v)
}
}
if final != missingVal {
v = s.validateType(final, argType)
}
- return v
+ return unwrap(v)
}
// Build the arg list.
@@ -767,10 +774,7 @@ func (s *state) evalCall(dot, fun reflect.Value, isBuiltin bool, node parse.Node
s.at(node)
s.errorf("error calling %s: %w", name, err)
}
- if v.Type() == reflectValueType {
- v = v.Interface().(reflect.Value)
- }
- return v
+ return unwrap(v)
}
// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
index a0432a588d..1a839a641b 100644
--- a/src/text/template/exec_test.go
+++ b/src/text/template/exec_test.go
@@ -491,6 +491,7 @@ var execTests = []execTest{
{"or pipe-false", "{{0 | or 0}}", "0", nil, true},
{"boolean if", "{{if and true 1 `hi`}}TRUE{{else}}FALSE{{end}}", "TRUE", tVal, true},
{"boolean if not", "{{if and true 1 `hi` | not}}TRUE{{else}}FALSE{{end}}", "FALSE", nil, true},
+ {"boolean if pipe", "{{if true | not | and 1}}TRUE{{else}}FALSE{{end}}", "FALSE", nil, true},
// Indexing.
{"slice[0]", "{{index .SI 0}}", "3", tVal, true},