-
Notifications
You must be signed in to change notification settings - Fork 18k
spec: range over integer expressions underspecified #65137
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
Comments
Related : #61405 (comment) If it is not problematic and not too late, I would remove the assignment form altogether. Then, no need to spec it either. |
This would mean
would not be allowed, as 256 is not assignable to uint8, although the actual values being assigned, 0, 1, ...., 255, are assignable? (Personally I think that is fine, if that is more consistent with other rules. Just a weird corner case.) |
@cherrymui Correct. I agree it's odd. But it would match the behavior of var u uint8
for u = 0; u < 256; u++ {} which is currently also not permitted. Note that for u := range 256 {} will be ok. |
Given a variable
|
The workaround is straightforward: var u uint8
for i := range n {
u = uint8(i)
println(u)
} |
Better yet var u uint8
for range n{
print(u)
u++
} Now if n is 256, there is still no issue. |
@gazerro Note that your example never worked if As @cherrymui has pointed out, these are really esoteric corner cases. Most of the time there's simply no issue here. If it turns out that we're too restrictive for practical purposes, we can relax the rules in the future, based on experience gained. But if we don't lock down things now, we won't be able to make changes later, once enough code is using behavior that we might consider incorrect. |
@griesemer my example works if |
@gazerro The direct translation of #65137 (comment) would be (https://go.dev/play/p/O4ZaNJeuJUG?v=gotip):
This fails to compile with:
|
Another question is, even if we keep the assignment form, why is it even possible for the type of the iteration variable to be I would have it be Edit2: oh I think I understand now that it is using an integer number n as a generator of n typed values starting from 0. |
Change https://go.dev/cl/556398 mentions this issue: |
Add missing checks for the case where the range expression is a (possibly untyped) constant integer expression. Add context parameter to assignVar for better error message where the expression is part of a range clause. Also, rename s/expr/Expr/ where it denotes an AST expression, for clarity. Fixes #65133. For #65137. Change-Id: I72962d76741abe79f613e251f7b060e99261d3ae Reviewed-on: https://go-review.googlesource.com/c/go/+/556398 Run-TryBot: Robert Griesemer <[email protected]> Auto-Submit: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
New semantics SGTM. |
Change https://go.dev/cl/557596 mentions this issue: |
New semantics SGTM too.
Oof. I suspect this is another consequence of our fuzzy IR. Ideally the compiler should have ICE'd instead. |
@gopherbot please consider this for backport to 1.22. It's missing documentation for 1.22. |
Backport issue(s) opened: #65413 (for 1.22). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases. |
Change https://go.dev/cl/559875 mentions this issue: |
…ge over integer Also: report language version (plus date) in spec header. For #65137. Change-Id: I4f1d220d5922c40a36264df2d0a7bb7cd0756bac Reviewed-on: https://go-review.googlesource.com/c/go/+/557596 TryBot-Bypass: Robert Griesemer <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/go/+/559875
Add missing checks for the case where the range expression is a (possibly untyped) constant integer expression. Add context parameter to assignVar for better error message where the expression is part of a range clause. Also, rename s/expr/Expr/ where it denotes an AST expression, for clarity. Fixes golang#65133. For golang#65137. Change-Id: I72962d76741abe79f613e251f7b060e99261d3ae Reviewed-on: https://go-review.googlesource.com/c/go/+/556398 Run-TryBot: Robert Griesemer <[email protected]> Auto-Submit: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
Also: report language version (plus date) in spec header. Fixes golang#65137. Change-Id: I4f1d220d5922c40a36264df2d0a7bb7cd0756bac Reviewed-on: https://go-review.googlesource.com/c/go/+/557596 TryBot-Bypass: Robert Griesemer <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
The following code
prints the values 0, 1, 2, ... 255, 0, 1; that is the integer "wraps around". This seems incorrect, but the spec is silent on the subject.
I believe the rules need to be extended such that if:
a) the iteration variable is already declared (
u
in the example above):b) the iteration variable is being declared (as in
for u := range x
):int
, the constant must be representable as anint
, and the iteration variable will be of typeint
I believe these rules follow more or less from the existing prose (assignment to the iteration variables happens as in an assignment statement), but the fact that the compiler and type checkers get this wrong is an indication that we need more precise prose or better examples.
We need to pin this down before the 1.22 release otherwise we may not be able to make these changes anymore in a backward-compatible way.
cc: @rsc
The text was updated successfully, but these errors were encountered: