go icon indicating copy to clipboard operation
go copied to clipboard

text/template: slice builtin does not work with arrays as described in documentation

Open duncanharris opened this issue 5 years ago • 8 comments

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

duncanharris avatar Jun 15 '20 15:06 duncanharris

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")
	}

duncanharris avatar Jun 15 '20 15:06 duncanharris

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.

duncanharris avatar Jun 15 '20 16:06 duncanharris

@mvdan

andybons avatar Jun 15 '20 18:06 andybons

can be resolved by inserting the following code into func slice before switch v.Kind() similar to that in the index builtin

@duncanharris that sounds like the right fix to me. Want to send a CL with tests?

mvdan avatar Jun 16 '20 13:06 mvdan

@mvdan Can you change the labels on this (remove NeedsInvestigation, add NeedsFix?) and assign to me?

duncanharris avatar May 11 '21 10:05 duncanharris

Done.

mvdan avatar May 11 '21 10:05 mvdan

Change https://golang.org/cl/318769 mentions this issue: text/template: fix slice builtin for pointers

gopherbot avatar May 11 '21 12:05 gopherbot

Change https://go.dev/cl/727400 mentions this issue: text/template: fix slice builtin for pointers to arrays

gopherbot avatar Dec 05 '25 20:12 gopherbot