Skip to content

go/printer: can print an invalid return statement depending on position info #32854

Closed

Description

@mvdan

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

go version devel +2e0cd2aef5 Fri Jun 28 20:10:05 2019 +0000 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What did you do?

https://play.golang.org/p/oxljScGL89r

What did you expect to see?

A valid program, like:

func f() {
	return call()

}

What did you see instead?

The return call() being printed separately, which means two statements instead of one.

func f() {
	return
		call()

}

To make this more obvious, gofmt formats the last piece of code as:

func f() {
	return
	call()

}

I encountered this while writing a program to modify source code. Surprisingly, I ended up with code that wouldn't compile, and figured out it was because the printer wasn't doing the right thing.

I assume this is a small bug that can be fixed, such as not allowing a newline in this case. I'll investigate a bit. /cc @griesemer

Activity

  1. added
    NeedsFixThe path to resolution is known, but the work has not been done.
    on Jun 29, 2019
  2. self-assigned this
    on Jun 29, 2019
  3. mvdan commented on Jun 29, 2019

    @mvdan
    MemberAuthor

    I realise that this could qualify as "abusing" the syntax tree nodes. However, I don't see why go/printer should ever write incorrect or different code. The only alternative would be to write lots of code to always make sure that the positions are OK, which I'm not sure is possible.

  4. av86743 commented on Jun 29, 2019

    @av86743

    Conceivably, your updated AST is not a valid one. Perhaps you can verify this using one of the AST library predicates/validators?

  5. mvdan commented on Jun 29, 2019

    @mvdan
    MemberAuthor

    I'd disagree. Even if you print a syntax tree with an empty fileset, the printer should still print a valid program, even if the style ends up looking weird.

    For example, other similar statements like go and defer don't have this same bug, so I think this is simply human error. The fix is also trivial - I'm finishing the test now.

  6. av86743 commented on Jun 29, 2019

    @av86743

    So you are unable to verify whether your generated AST is valid?

  7. gopherbot commented on Jun 29, 2019

    @gopherbot
    Contributor

    Change https://golang.org/cl/184121 mentions this issue: go/printer: never print a newline before the returned results

  8. mvdan commented on Jun 29, 2019

    @mvdan
    MemberAuthor

    Sorry, I don't know what you mean. The syntax tree is perfectly valid. The position information obtained via the fileset is a bit weird, but still, I don't think that should lead to the printer producing incorrect output and no error.

    I also don't know what validators you're talking about. You can validate the syntax tree example I gave above, if that helps.

  9. griesemer commented on Jun 30, 2019

    @griesemer
    Contributor

    @mvdan I agree this is a bug. Unfortunately, the go/printer can produce incorrect formatting in some cases.

  10. mvdan commented on Jul 1, 2019

    @mvdan
    MemberAuthor

    I understand these edge cases are super rare, primarily because one needs to craft a syntax tree manually. It's impossible for gofmt to run into this bug, I think. In any case, I'm happy to send patches like this one if you're happy to review them.

  11. griesemer commented on Jul 1, 2019

    @griesemer
    Contributor

    @mvdan I can review them but it's not a high priority. The shorter the better, of course :-)

  12. added this to the Go1.14 milestone on Sep 19, 2019
  13. locked and limited conversation to collaborators on Sep 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions