Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[]int32 and []rune cannot exist in the same type switch #27955

Closed
valarauca opened this issue Oct 1, 2018 · 6 comments
Closed

[]int32 and []rune cannot exist in the same type switch #27955

valarauca opened this issue Oct 1, 2018 · 6 comments

Comments

@valarauca
Copy link

valarauca commented Oct 1, 2018

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.11 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/cody/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/cody/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
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-build659522590=/tmp/go-build -gno-record-gcc-switches"

What did you do?

int32 and rune collide with one-another in type reflection

https://play.golang.org/p/gXKj4J2OuA5

Furthermore []int32 and []rune collide with one-another

https://play.golang.org/p/63ZrNkv3VEa

What did you expect to see?

In short []int32 and []rune should both be able to exist within a type switch. According to the specification a rune is a Unicode Code Point. So []rune should be extremely restricted to which values it can hold, and in what order. As according to the Unicode consortium not all in32 are valid rune.

When writing something to accept interface{}, such a logger. Being able to distinguish between []rune and []int32 when accepting a message, or key-value to populate with a log message. Is rather important as these arguments will formatted vastly different. []rune can likely be formatted a string, while []int32 should formatted as [ a, b, c, d] to pleasantly present a list of values.

In short either the reference should state rune is just an alias of int32, and has no special meaning. Or the compiler should enforce the special meaning given in the reference.

What did you see instead?

A Compiler Error.

@ianlancetaylor
Copy link
Member

This is working as documented. The type rune is an alias for the type int32, as if defined as type rune = int32. So they really are the same underlying type.

This program prints OK: https://play.golang.org/p/RGZNdC7pclA .

@valarauca
Copy link
Author

valarauca commented Oct 1, 2018

@ianlancetaylor then can the reference be updated to state that rune is not a codepoint, as the compiler makes no attempt to enforce this, and programmers should not treat rune differently from int32?

@ianlancetaylor
Copy link
Member

@valarauca Which reference are you referring to?

@valarauca
Copy link
Author

valarauca commented Oct 1, 2018

The language reference specification link which states:

A rune literal represents a rune constant, an integer value identifying a Unicode code point.

As int32 can be passed to rune argument as demonstrated here without a compiler error, and casts are not checked for illegal values see here.

So if this could be changed to:

A rune literal represents a rune constant, an integer value identifying a Unicode code point, not a valid Unicode code point.

Also a note should be added that compile time type easure between int32 and rune occurs. To avoid confusion in the future. As while the reference for rune does point to the Constants it isn't mentioned that int32 and rune are interchangeable, while it does for true/false/iota.

@valarauca
Copy link
Author

Lastly should I open an issue that

fmt.Printf("Type: %T\n", rune('a'))

Prints Type: int32

that seems like an error?

@ianlancetaylor
Copy link
Member

I don't think your suggested rewrite is correct. A rune literal, which is one or more characters written within single quotes, is a Unicode point. And a rune literal has type rune. But a rune literal, which is an expression, is not the same as the type rune, which is, of course, a type. The type rune is defined at https://golang.org/ref/spec#Numeric_types as an alias for int32.

Similarly, your %T example is not an error, since the type rune is an alias for int32.

@golang golang locked and limited conversation to collaborators Oct 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants