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

Compile error: if-statement with assignment #35932

Closed
flxkl opened this issue Dec 2, 2019 · 1 comment
Closed

Compile error: if-statement with assignment #35932

flxkl opened this issue Dec 2, 2019 · 1 comment

Comments

@flxkl
Copy link

flxkl commented Dec 2, 2019

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

$ go version
go version go1.13.4 linux/amd64

Does this issue reproduce with the latest release?

Yes.
I have not tried earlier Go versions.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/felix/.cache/go-build"
GOENV="/home/felix/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/felix/.gvm/pkgsets/go1.13.4/global:/home/felix/host/repositories/polimon"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/felix/.gvm/gos/go1.13.4"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/felix/.gvm/gos/go1.13.4/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build956762970=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I tried to compile the following program with the uncommented if-statement.

package main

import "fmt"

type S struct {
    value int
}

func main() {
    if x := (S{5}); x.value != 5 {
        fmt.Printf("x\n")
    }

    // The following commented if-statement, if uncommented does not compile.
    // Note that there are no parentheses around S{5} as in the above
    // if-statement.

    //if y := S{5}; y.value != 5 {
    //    fmt.Printf("y\n")
    //}

    // The compile error is:
    //   ./main.go:18:14: syntax error: y := S used as value
    //   ./main.go:28:1: syntax error: non-declaration statement outside function body
    // In another program, with essentially the same if-statement, the compile
    // error is:
    //   time_test.go:51:8: expected boolean expression, found assignment (missing parentheses around composite literal?)
}

What did you expect to see?

I would expect that the program with the uncommented if-statement also compiles.

What did you see instead?

A compile error (see code above).
The problem seems to be the assignment y := S{5} in the if-statement. When putting parentheses
around the struct, i.e., y := (S{5}), the program compiles. Is this a bug in the parser (precedence of := over S{5})?

@ALTree
Copy link
Member

ALTree commented Dec 2, 2019

Hi,

this is a known parsing ambiguity in the language grammar. From the Composite literals Section of the Specification:

A parsing ambiguity arises when a composite literal using the TypeName form of the LiteralType appears as an operand between the keyword and the opening brace of the block of an "if", "for", or "switch" statement, and the composite literal is not enclosed in parentheses, square brackets, or curly braces. In this rare case, the opening brace of the literal is erroneously parsed as the one introducing the block of statements. To resolve the ambiguity, the composite literal must appear within parentheses.

if x == (T{a,b,c}[i]) { … }
if (x == T{a,b,c}[i]) { … }

Closing here.

@ALTree ALTree closed this as completed Dec 2, 2019
@golang golang locked and limited conversation to collaborators Dec 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants