From: Roger Peppe Date: Thu, 21 Jul 2011 23:53:25 +0000 (+1000) Subject: exp/template: fix action variable declarations inside range X-Git-Tag: weekly.2011-07-29~91 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=47647b9865c9d3dbcf95c650420b0aaeeb6a3aff;p=gostls13.git exp/template: fix action variable declarations inside range R=r CC=golang-dev https://golang.org/cl/4807043 --- diff --git a/src/pkg/exp/template/exec.go b/src/pkg/exp/template/exec.go index d5a86d8722..74d529c2f6 100644 --- a/src/pkg/exp/template/exec.go +++ b/src/pkg/exp/template/exec.go @@ -172,6 +172,8 @@ func isTrue(val reflect.Value) (truth, ok bool) { func (s *state) walkRange(dot reflect.Value, r *rangeNode) { defer s.pop(s.mark()) val, _ := indirect(s.evalPipeline(dot, r.pipe)) + // mark top of stack before any variables in the body are pushed. + mark := s.mark() switch val.Kind() { case reflect.Array, reflect.Slice: if val.Len() == 0 { @@ -188,6 +190,7 @@ func (s *state) walkRange(dot reflect.Value, r *rangeNode) { s.setVar(2, reflect.ValueOf(i)) } s.walk(elem, r.list) + s.pop(mark) } return case reflect.Map: @@ -205,6 +208,7 @@ func (s *state) walkRange(dot reflect.Value, r *rangeNode) { s.setVar(2, key) } s.walk(elem, r.list) + s.pop(mark) } return default: diff --git a/src/pkg/exp/template/exec_test.go b/src/pkg/exp/template/exec_test.go index 36eaabe5f0..cba0d5a97c 100644 --- a/src/pkg/exp/template/exec_test.go +++ b/src/pkg/exp/template/exec_test.go @@ -331,6 +331,7 @@ var execTests = []execTest{ {"range $x MSIone", "{{range $x := .MSIone}}<{{$x}}>{{end}}", "<1>", tVal, true}, {"range $x $y MSIone", "{{range $x, $y := .MSIone}}<{{$x}}={{$y}}>{{end}}", "", tVal, true}, {"range $x PSI", "{{range $x := .PSI}}<{{$x}}>{{end}}", "<21><22><23>", tVal, true}, + {"declare in range", "{{range $x := .PSI}}<{{$foo:=$x}}>{{end}}", "<21><22><23>", tVal, true}, // Cute examples. {"or as if true", `{{or .SI "slice is empty"}}`, "[3 4 5]", tVal, true},