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

cmd/compile: const decl with missing RHS interpreted subtly differently with 1.18 #49157

Closed
go101 opened this issue Oct 25, 2021 · 14 comments
Closed
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. release-blocker
Milestone

Comments

@go101
Copy link

go101 commented Oct 25, 2021

The current spec says:

Within a parenthesized const declaration list the expression list may be omitted from any but the first ConstSpec. Such an empty list is equivalent to the textual substitution of the first preceding non-empty expression list and its type if any. Omitting the list of expressions is therefore equivalent to repeating the previous list.

By the explanation, the following two declarations are equivalent but are not actually (assume they are in local blocks):

const (
    A = iota
    iota = iota
    B
    C
)
const (
    A = iota
    iota = iota
    B = iota
    C
  )

It would be better to change "textual" into "lexical".

@ianlancetaylor
Copy link
Contributor

CC @griesemer

@ianlancetaylor ianlancetaylor added Documentation NeedsFix The path to resolution is known, but the work has not been done. labels Oct 26, 2021
@ianlancetaylor ianlancetaylor added this to the Backlog milestone Oct 26, 2021
@griesemer griesemer self-assigned this Oct 26, 2021
@griesemer
Copy link
Contributor

Nice pathological case!

@robpike
Copy link
Contributor

robpike commented Oct 26, 2021

I am missing what the pathology is, and why s/textual/lexical/ makes a difference. Please fill me in.

@griesemer
Copy link
Contributor

In the first example, simply repeating the last present RHS where it is omitted leads to a different result (than leaving the RHS away) because the iota on the RHS of B = iota (after manually filling it in) is the user-defined, not the built-in iota. This effect is only possible for local constant declarations; at the package level we get a cycle error due to the different scope rules at the package level (see the example for all four cases).

Agreed that I don't know how using "lexical" would make this clearer. But stating that"Such an empty list is equivalent to the textual substitution of the first preceding non-empty expression list and its type if any." seems not quite correct.

@robpike
Copy link
Contributor

robpike commented Oct 26, 2021

I just wrote,

"I still don't see the problem. You're created a new variable called iota, so of course it's different."

and in writing that saw the problem. Wow, nice corner case.

@go101
Copy link
Author

go101 commented Oct 26, 2021

In fact, this is not an iota specific issue:

package main

const X = 3

func main() {
	const (
		X = X + X
		Y
	)
	
	println(X, Y)
}

@griesemer griesemer changed the title spec: inaccuracy in iota explanation spec: be more precise in explaining semantics of ConstSpec with missing RHS Oct 26, 2021
@griesemer griesemer modified the milestones: Backlog, Go1.19 May 12, 2022
@griesemer
Copy link
Contributor

Looking at this again, it turns out that in Go 1.18 (with the new type checker) we actually get exactly the result as prescribed by the spec. For this example:

package main

const X = 3

func main() {
	const (
		X = X + X
		Y
	)
	println(X, Y)
}

Running with Go 1.18 we get the result 6 and 12, which corresponds exactly to using textually X + X for Y as the spec prescribes.

Running with 1.17 we get the result 6 and 6, corresponding to a copy of the syntax tree for X + X with the variables X resolved to the outer `X.

We have two possibilities:

  1. The spec is wrong and we have a regression in 1.18.
  2. The spec is correct and 1.18 fixed a long-existing bug.

There is a backward-compatibility issue here but this is a pathological situation that is unlikely to occur in correct code in the wild, and since 1.18 is out we have not heard any complaints about this.

Thus I am inclined to go 2) and close this issue.

@ianlancetaylor @robpike @rsc for feedback.

@griesemer griesemer added NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. release-blocker and removed Documentation NeedsFix The path to resolution is known, but the work has not been done. labels Jun 28, 2022
@griesemer
Copy link
Contributor

griesemer commented Jun 28, 2022

Marking as release blocker in case we decide that this needs to be handled as a regression.

@griesemer griesemer changed the title spec: be more precise in explaining semantics of ConstSpec with missing RHS cmd/compile: const decl with missing RHS interpreted subtly differently with 1.18 Jun 28, 2022
@robpike
Copy link
Contributor

robpike commented Jun 28, 2022

2

@ianlancetaylor
Copy link
Contributor

Current gccgo prints 6 6, like Go 1.17.

I'm fine with changing that.

@griesemer
Copy link
Contributor

Closing as working as intended since Go 1.18, per feedback.

@griesemer griesemer removed their assignment Jun 28, 2022
@ianlancetaylor
Copy link
Contributor

We should add a test case or two for this if we don't already have one.

@griesemer
Copy link
Contributor

@ianlancetaylor Yes, I was planning to do that.

@gopherbot
Copy link

Change https://go.dev/cl/414795 mentions this issue: test: add more tests for const decls with ommitted RHS expressions

gopherbot pushed a commit that referenced this issue Jun 28, 2022
Add analogous tests to go/types and types2 test suites.
Make sure "assert" built-in is available in type-checker
tests.

For #49157.
For #53585.

Change-Id: I092901ecb43eb4833c09bd8f5e38efbe0285babe
Reviewed-on: https://go-review.googlesource.com/c/go/+/414795
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
jproberts pushed a commit to jproberts/go that referenced this issue Aug 10, 2022
Add analogous tests to go/types and types2 test suites.
Make sure "assert" built-in is available in type-checker
tests.

For golang#49157.
For golang#53585.

Change-Id: I092901ecb43eb4833c09bd8f5e38efbe0285babe
Reviewed-on: https://go-review.googlesource.com/c/go/+/414795
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
@golang golang locked and limited conversation to collaborators Jun 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. release-blocker
Projects
Development

No branches or pull requests

5 participants