Skip to content

cmd/compile: unable to use composite literal directly as part of range expression #69017

Not planned
@nan0tube

Description

@nan0tube

Go version

go version go1.23.0 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/user/.cache/go-build'
GOENV='/home/user/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/user/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/user/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.0'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/user/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/user/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2151432987=/tmp/go-build -gno-record-gcc-switches'

What did you do?

package main

import "fmt"

type S struct {
	Slice []int
}

func main() {
	// Works.
	s := S{}
	for _, v := range s.Slice {
		fmt.Print(v)
	}

	// Error: syntax error: unexpected . at end of statement
	for _, v := range S{}.Slice {
		fmt.Print(v)
	}
}

https://go.dev/play/p/t_G0ZOb51EG

The statement for _, v := range S{}.Slice {} throws a syntax error due to the direct use of composite literal S{} as part of the range expression.

Will be good to see composite literal being supported directly inside range expression, especially with the introduction of range-over-func (e.g. range interval{a, b}.Step()).

As a workaround, the statement for _, v := range (S{}).Slice {} works but appears unintuitive, when expression S{}.Slice can be trivially used in most other statements.

What did you see happen?

syntax error: unexpected . at end of statement on the line where the composite literal is used as part of the range expression.

What did you expect to see?

No syntax error.

Activity

zephyrtronium

zephyrtronium commented on Aug 22, 2024

@zephyrtronium
Contributor

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.

Per https://go.dev/ref/spec#Composite_literals. This is working as intended. Parsing the brackets as a composite literal would require either type information in the parser or unbounded lookahead, both of which are properties Go has historically sought to avoid.

zigo101

zigo101 commented on Aug 22, 2024

@zigo101

Use either (S{}.Slice) or (S{}).Slice.

Similar case: if _ = S{}; true {}.

cherrymui

cherrymui commented on Aug 22, 2024

@cherrymui
Member

As @zephyrtronium and @zigo101 mentioned, this works as intended, and has a simple workaround. Thanks.

nan0tube

nan0tube commented on Aug 23, 2024

@nan0tube
Author

Got it, thanks all!

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

    compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @zephyrtronium@nan0tube@gopherbot@cherrymui@zigo101

        Issue actions

          cmd/compile: unable to use composite literal directly as part of range expression · Issue #69017 · golang/go