text/template: slice builtin does not work with arrays as described in documentation
What version of Go are you using (go version)?
$ go version go version go1.14.4 linux/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="on" GOARCH="amd64" GOBIN="" GOCACHE="/home/duncan/.cache/go-build" GOENV="/home/duncan/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/duncan/.local" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/home/duncan/sdk/go1.14.4" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/home/duncan/sdk/go1.14.4/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/home/duncan/.local/src/github.com/duncanharris/template-slice-bug/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build531232634=/tmp/go-build -gno-record-gcc-switches" GOROOT/bin/go version: go version go1.14.4 linux/amd64 GOROOT/bin/go tool compile -V: compile version go1.14.4 uname -sr: Linux 5.3.0-53-generic Distributor ID: Ubuntu Description: Ubuntu 18.04.4 LTS Release: 18.04 Codename: bionic /lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27. gdb --version: GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
What did you do?
Tried to use an array with the text/template builtin slice function.
https://play.golang.org/p/lrdcuk7gkvU
Docs at https://golang.org/pkg/text/template/ say:
Arguments may evaluate to any type; if they are pointers the implementation automatically indirects to the base type when required.
and
slice ... The first argument must be a string, slice, or array.
Note that the builtin index function plays fine with arrays in both cases:
https://play.golang.org/p/DEeEWit74YL
What did you expect to see?
[Hello]
output in at least one of the cases
What did you see instead?
template: test:1:2: executing "test" at <slice .>: error calling slice: reflect.Value.Slice: slice of unaddressable array
template: test:1:2: executing "test" at <slice .>: error calling slice: can't slice item of type *[1]string
The pointer to array case can be resolved by inserting the following code into func slice before switch v.Kind() similar to that in the index builtin:
var isNil bool
if v, isNil = indirect(v); isNil {
return reflect.Value{}, fmt.Errorf("slice of nil pointer")
}
The plain array case does work if I put the array in a struct and pass a pointer to the struct: https://play.golang.org/p/cSRHe8MN3wS
However still does not work if the struct contains a pointer to an array whereas the documentation implies it should.
@mvdan
can be resolved by inserting the following code into
func slicebeforeswitch v.Kind()similar to that in theindexbuiltin
@duncanharris that sounds like the right fix to me. Want to send a CL with tests?
@mvdan Can you change the labels on this (remove NeedsInvestigation, add NeedsFix?) and assign to me?
Done.
Change https://golang.org/cl/318769 mentions this issue: text/template: fix slice builtin for pointers
Change https://go.dev/cl/727400 mentions this issue: text/template: fix slice builtin for pointers to arrays