
Description
What version of Go are you using (go version
)?
go1.10.4 linux/amd64
Does this issue reproduce with the latest release?
Haven't tried.
What operating system and processor architecture are you using (go env
)?
go env
Output
GOARCH="amd64" GOBIN="" GOCACHE="/home/<>/.cache/go-build" GOEXE="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/home/<>/go" GORACE="" GOROOT="/usr/lib/go-1.10" GOTMPDIR="" GOTOOLDIR="/usr/lib/go-1.10/pkg/tool/linux_amd64" GCCGO="/usr/bin/gccgo" CC="gcc" CXX="g++" CGO_ENABLED="1" 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-build779194954=/tmp/go-build -gno-record-gcc-switches"
What did you do?
Defined function with signature: func variadic(args ...interface{})
and attempted to call it by unpacking a slice: variadic([]int{1,2,3}...)
.
What did you expect to see?
Compilation succeeds.
What did you see instead?
Conversion error from []int to []interface{}.
The reason why is understood, as per FAQ:
If the final argument is assignable to a slice type []T, it may be passed unchanged as the value for a ...T parameter if the argument is followed by .... In this case no new slice is created.
However, the first sentence suggests that this optimization should not have occurred because []int
is not assignable to []interface{}
:
A value x is assignable to a variable of type T ("x is assignable to T") if one of the following conditions applies:
x's type is identical to T
False, []int
is not of type []interface{}
.
x's type V and T have identical underlying types and at least one of V or T is not a defined type.
False, both types are defined.
T is an interface type and x implements T.
False, []int
is not an interface.
x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a defined type.
False, []int
is not a channel.
x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
False, []int
is not nil
.
x is an untyped constant representable by a value of type T.
False, []int
is a type.
Since []int
is not assignable to []interface{}
the slice should have been unpacked and each element passed individually to the variadic function.
There are several related issues (eg. #1616, #18547, #27795) that expose the same problem, probably more but none appear to go further than claiming that this is "working as intended".
If I wanted to pass the []int as-is, I could have simply omitted unpacking by writing variadic([]int{1,2,3})
instead of variadic([]int{1,2,3}...)
. By typing the latter, I explicitly say "I want to unpack this slice". The compiler however decided to take my statement as suggestion since it believed []int
is assignable to []interface{}
and decided not to not honor my request, instead passing the slice as-is.
I this believe is in error.