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: unnecessary error reports #22619

Closed
dotaheor opened this issue Nov 7, 2017 · 16 comments

Comments

Projects
None yet
4 participants
@dotaheor
Copy link

commented Nov 7, 2017

Please answer these questions before submitting your issue. Thanks!

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

go version go1.9.2 linux/amd64

Does this issue reproduce with the latest release?

yes

What did you do?

package main

func main() {
	var c chan bool
	
	select {
	default:
		goto A // label A not defined
		A:     // syntax error: missing statement after label
	case <-c:
		goto B // ok
		B:     // ok
	}
	
	select {
	default:
	{
		goto C // ok
		C:     // ok
	}
	case <-c:
		goto D // ok
		D:     // ok
	}
	
	select {
	case <-c:
		goto X // label X not defined
		X:     // syntax error: missing statement after label
	default:
		goto Y // ok
		Y:     // ok
	}
	
	select {
	case <-c:
	{
		goto W // ok
		W:     // ok
	}
	default:
		goto Z // ok
		Z:     // ok
	}
}

same for cases in switch.

What did you expect to see?

No errors are reported.

What did you see instead?

vet: main.go: main.go:10:2: expected statement, found 'case' (and 1 more errors)
vet: no files checked
exit status 1

@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Nov 7, 2017

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Nov 7, 2017

@griesemer

This comment has been minimized.

Copy link
Contributor

commented Nov 7, 2017

Is this a compiler or vet issue? It's not clear from your description. Please describe exactly what you did. (Your "What did you do"? report just shows some code).

FWIW, I get

./x.go:9:4: syntax error: missing statement after label
./x.go:29:4: syntax error: missing statement after label

as the only errors with cmd/compile or go vet.

Please clarify.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Nov 7, 2017

I can recreate the problem with the Go 1.9 cmd/vet. But it's fixed on tip.

Thanks for the report, but since it's been fixed I'm going to close this. I don't think this is important enough to backport to 1.9.

@dotaheor

This comment has been minimized.

Copy link
Author

commented Nov 7, 2017

@griesemer
yes, I forgot to attach the compiler errors too. It is both a bug of the compiler and vet.

@ianlancetaylor
glad to know it is fixed.

@dotaheor

This comment has been minimized.

Copy link
Author

commented Nov 7, 2017

@ianlancetaylor
I just updated the tip and rebuilt it.
But I found the errors are still reported.

The go version shows

go version devel +79f6c280b8 Tue Nov 7 22:06:35 2017 +0000 linux/amd64
@griesemer

This comment has been minimized.

Copy link
Contributor

commented Nov 7, 2017

@dotaheor Please describe your exact steps (compiler, go vet invocation) and errors you see.

@dotaheor

This comment has been minimized.

Copy link
Author

commented Nov 7, 2017

main.go:

package main

func main() {
	var c chan bool
	
	select {
	case <-c:
	{
		goto A
		A: // ok
	}
	case <-c:
		goto B
		B: // syntax error: missing statement after label
	case <-c:
		goto C
		C: // ok
	}
}

'~/go/src/github.com/golang/go/bin/go build main.go`:

./main.go:14:4: syntax error: missing statement after label
@dotaheor

This comment has been minimized.

Copy link
Author

commented Nov 7, 2017

However, vet is fixed on tip.
~/go/src/github.com/golang/go/bin/go build vet main.go is ok.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Nov 7, 2017

The error is correct according to the language spec, though the reason is a little complicated. A label must always appear before a statement. However, a statement may be a single semicolon, representing the empty statement. And that semicolon may be omitted before a } character. So that is what is happening for your labels A and C: a semicolon is omitted before the '}', and that omitted semicolon is the empty labeled statement. For B no semicolon is omitted, there is no statement, and so you get a compiler error.

@dotaheor

This comment has been minimized.

Copy link
Author

commented Nov 7, 2017

But why must there be at least one statement following a label?
I think there are really some reasonable uses like the second case.
Surely the second goto can be replaced with a break.
But in doing programming, for debug purpose, we may temperately
comment off and on the statements following the the label B for multiple times.
Forcing programmers to change the goto into a break, and back and forth, is inconvenient.

On the other hand, from the implementation view,
inserting a ; after the declaration of label B is quite easy.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Nov 7, 2017

@dotaheor Well, now you are talking about a language change. Perhaps it would be a straightforward change, I don't know. Someone would have to work through all the possible issues and make a language change proposal.

For your purposes, you could simply write B:;.

@dotaheor

This comment has been minimized.

Copy link
Author

commented Nov 7, 2017

OK, a quite good workaround.

@dotaheor

This comment has been minimized.

Copy link
Author

commented Nov 7, 2017

@ianlancetaylor
but I can't find the rule in spec.

@griesemer

This comment has been minimized.

Copy link
Contributor

commented Nov 8, 2017

@dotaheor A labeled statement is simply a statement. A labeled statement may have an empty statement following the ":", and an empty statement is literally nothing.

But, all statements must be followed by a semicolon (*) because statements appear in statement lists.

It would be extremely irregular in the grammar to have some statements be followed by semicolons and not others. (*) Finally, independently, semicolons may be elided before a closing "}".

Altogether, this is what leads to the current behavior. You can be assured that this is not coincidental and has been carefully thought through. The rules are like they are to make a) the syntax regular (all statements must be followed by semicolons), and b) the case where a statement is immediately followed by a closing "}" of a block not overly onerous .

These rules are in the syntax of the spec, and in the prose.

@griesemer

This comment has been minimized.

Copy link
Contributor

commented Nov 8, 2017

PS: Most of the time a semicolon does not need to be written because of the semicolon insertion rule ( https://tip.golang.org/ref/spec#Semicolons ). This works out for pretty much all statements, but because empty statements have no tokens (they are empty), the token immediately before determines if a semicolon is inserted or not at the end of a line. In a labelled empty statement, that last token is ":", and ":" does not automatically cause a semicolon to be inserted at the end of a line.

If there was any change to be made, one could perhaps propose that a semicolon can be omitted before a "case" or "default" keyword as well, and then this would work out without error. But I am not recommending such a change; it doesn't seem worthwhile the additional complexity for a corner case that is rare.

@dotaheor

This comment has been minimized.

Copy link
Author

commented Nov 8, 2017

Ah, it is quite complicated and subtle.

I may make a proposal that inserting a semicolon right after each label declaration.,
but I think this is really not very worthwhile.

Thanks for the detailed explanations.

@golang golang locked and limited conversation to collaborators Nov 8, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.