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
Labels
Documentation NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@mdempsky
Copy link
Member

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 commented Apr 7, 2018

Somewhat related: #21982.

@mdempsky
Copy link
Member Author

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 commented Apr 7, 2018

doesn't integer constants include rune constants?

@cznic
Copy link
Contributor

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 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 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 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

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.

@ianlancetaylor ianlancetaylor added the NeedsFix The path to resolution is known, but the work has not been done. label Jun 29, 2018
@ianlancetaylor ianlancetaylor modified the milestones: Go1.11, Unplanned Jun 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants