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

spec: inconsistency about allowable conversions of numeric constants to strings #24745

Open
mdempsky opened this issue Apr 7, 2018 · 8 comments
Open
Assignees
Milestone

Comments

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Apr 7, 2018

In section "Conversions", the Go spec says:

A constant value x can be converted to type T if x is representable by a value of T. As a special case, an integer constant x can be converted to a string type using the same rule as for non-constant x.

Note that "integer constants" are distinct from "rune constants", "float constants", etc.

However, the spec also includes two examples of conversions of rune literals to type string: string('x') and string('a').

cmd/compile and go/types allow these conversions. I assume gccgo does too, as utf8.RuneError is an untyped rune constant, and string(utf8.RuneError) appears a few times in the standard library.

I think the wording should be tweaked to "an integer or rune constant x".

Aside: I'd think we should relax it further to allow any integer value. We allow make([]byte, 1.0), so it seems inconsistent to not allow string(1.0).

/cc @griesemer

@mdempsky mdempsky added this to the Go1.11 milestone Apr 7, 2018
@mdempsky mdempsky changed the title spec: inconsistency about converting numeric constants to strings spec: inconsistency about allowable conversions of numeric constants to strings Apr 7, 2018
@mdempsky
Copy link
Member Author

@mdempsky mdempsky commented Apr 7, 2018

Somewhat related: #21982.

@mdempsky
Copy link
Member Author

@mdempsky mdempsky commented Apr 7, 2018

If the left operand of a constant shift expression is an untyped constant, the result is an integer constant;

This suggests in the code below that 'a' << 1 should be an integer constant, so x should be given the default type int, and the blank assignment should succeed.

var x = 'a' << 1
var _ int = x

However, cmd/compile and go/types both give x the type rune, so the assignment is rejected.

@go101
Copy link

@go101 go101 commented Apr 7, 2018

doesn't integer constants include rune constants?

@cznic
Copy link
Contributor

@cznic cznic commented Apr 7, 2018

I also think 'x' is an integer constant. It's just its default type is rune.

@mdempsky
Copy link
Member Author

@mdempsky mdempsky commented Apr 7, 2018

rune is an alias for int32, which is defined as an integer type. But there doesn't appear to be any wording to suggest that "rune constants" are a subclass of "integer constants."

@cznic
Copy link
Contributor

@cznic cznic commented Apr 7, 2018

I think that 'x' is not (yet) a rune constant, but an untyped integer constant. In certain contexts, like in foo := 'x' it becomes a rune. In string('x') its default type (rune) is IMO not relevant. I think that it's in the later case actually (due to context) first converted to int, not rune, like in the (IMHO) equivalent string(120).

@mdempsky
Copy link
Member Author

@mdempsky mdempsky commented Apr 8, 2018

I think that 'x' is not (yet) a rune constant, but an untyped integer constant.

That's not what the Go spec says (emphasis added):

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

Rune constants are integer values, but not integer constants.

@griesemer griesemer self-assigned this Apr 9, 2018
@griesemer
Copy link
Contributor

@griesemer griesemer commented Apr 9, 2018

I agree with @mdempsky that there is at least some imprecision if not inconsistency in the spec in this area. We use mildly similar terminology for different purposes (integer value vs integer constant vs integer vs int type, etc.) and these terms are vaguely defined if at all.

I think we need to clearly define these terms in one place (consistent with existing use) and then this issue (and related ones) should become clear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.