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/go: always pass -lang to cmd/compile #66092

Open
go101 opened this issue Mar 4, 2024 · 16 comments
Open

cmd/go: always pass -lang to cmd/compile #66092

go101 opened this issue Mar 4, 2024 · 16 comments
Assignees
Labels
FixPending Issues that have a fix which has not yet been reviewed or submitted. GoCommand cmd/go
Milestone

Comments

@go101
Copy link

go101 commented Mar 4, 2024

Go version

go version go1.22.0 linux/amd64

Output of go env in your module/workspace:

.

What did you do?

main.go:

//go:build go1.21

package main

func main() {
	for i, p := 0, (*int)(nil); p == nil; println(p == &i) {
		p = &i
	}
}
go run main.go

What did you see happen?

true

What did you expect to see?

false

Note that when the -gcflags=-lang=go1.22 compiler flag is specified, then the "//go:build go1.xy" comment directive is respected (go run . with a go.mod file also respects it).

$ gotv 1.22. run main.go 
[Run]: $HOME/.cache/gotv/tag_go1.22.0/bin/go run main.go
false
$ gotv 1.22. run -gcflags=-lang=go1.22 main.go 
[Run]: $HOME/.cache/gotv/tag_go1.22.0/bin/go run -gcflags=-lang=go1.22 main.go
true
$ gotv 1.22. run .
[Run]: $HOME/.cache/gotv/tag_go1.22.0/bin/go run .
true
$ gotv 1.22. run -gcflags=-lang=go1.22 .
[Run]: $HOME/.cache/gotv/tag_go1.22.0/bin/go run -gcflags=-lang=go1.22 .
true
@bcmills bcmills changed the title com/go: the "//go:build go1.xy" comment directive is ignored in "go run main.go" mode cmd/compile: the "//go:build go1.xy" comment directive is ignored in "go run main.go" mode Mar 4, 2024
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Mar 4, 2024
@bcmills
Copy link
Contributor

bcmills commented Mar 4, 2024

This is closely related to

However, in the absence of any -lang flag, I expect cmd/compile to still apply whatever version information it has inferred from the //go:build directives, and it appears not to be doing so. This looks like a compiler bug.

@mknyszek mknyszek added this to the Backlog milestone Mar 4, 2024
@mknyszek mknyszek added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 4, 2024
@mknyszek
Copy link
Contributor

mknyszek commented Mar 4, 2024

CC @golang/compiler

@go101
Copy link
Author

go101 commented Mar 4, 2024

@bcmills
Just a btw question: it looks the -gcflags=-lang=go1.xy compiler flag is only applied to the seed files being passed to the compiler. Other involved source files in building will not be affected by the flag. Is this the intended design?

@mknyszek mknyszek changed the title cmd/compile: the "//go:build go1.xy" comment directive is ignored in "go run main.go" mode cmd/go: the "//go:build go1.xy" comment directive is ignored in "go run main.go" mode Mar 6, 2024
@mknyszek mknyszek added GoCommand cmd/go and removed compiler/runtime Issues related to the Go compiler and/or runtime. labels Mar 6, 2024
@mknyszek
Copy link
Contributor

mknyszek commented Mar 6, 2024

In runtime/compiler triage, we think this is a Go command issue? Is that right? Thanks.

@bcmills
Copy link
Contributor

bcmills commented Mar 6, 2024

I think it is a composite of a cmd/go bug (not passing the -lang flag) and a cmd/compile bug (not using //go:build version hints when -lang is not explicitly set).

The cmd/go bug should be fixed in #65612, so I suggest we focus the investigation in this issue on the cmd/compile side.

@bcmills bcmills changed the title cmd/go: the "//go:build go1.xy" comment directive is ignored in "go run main.go" mode cmd/compile: "//go:build go1.xy" versions ignored when -lang is not set Mar 6, 2024
@go101
Copy link
Author

go101 commented Apr 2, 2024

Will this be fixed in 1.22.3+?

@griesemer
Copy link
Contributor

When no -lang is specified, in general we don't know how to interpret //go:build lines in files because their interpretation may depend on the current -lang version.

cc: @rsc for input.

@go101
Copy link
Author

go101 commented Apr 3, 2024

Is it a good idea to use the version of the go command as the -lang arg?

@rsc
Copy link
Contributor

rsc commented Apr 3, 2024

@go101 Is the top comment wrong? It says got true, expected false for go run main.go, but with Go 1.21 I get false and Go 1.22 I get true. If you think there is a bug in Go 1.22, then did you mean "got false, expected true"?

@go101
Copy link
Author

go101 commented Apr 3, 2024

I mean the //go:build go1.21 line should matter, so that the results should be consistent with Go toolchain 1.21 and 1.22.

@rsc
Copy link
Contributor

rsc commented Apr 3, 2024

I'm just trying to puzzle through this all since I don't know what "gotv 1.22." does either...

@go101
Copy link
Author

go101 commented Apr 4, 2024

gotv is a tool used to switch Go toolchain versions conveniently: https://go101.org/apps-and-libs/gotv.html

gotv 1.22. means using the latest version prefixed by 1.22. It will be expanded to $HOME/.cache/gotv/tag_go1.22.0/bin/go. :)

@rsc
Copy link
Contributor

rsc commented Apr 5, 2024

For future bug reports it would help to use reproduction instructions that are limited to standard tooling.

@rsc
Copy link
Contributor

rsc commented Apr 5, 2024

Here is a clearer reproduction case:

% cd /tmp
% cat x.go
//go:build go1.21

package main

func main() {
	for i, p := 0, (*int)(nil); p == nil; check(p == &i) {
		p = &i
	}
}

func check(b bool) {
	if b {
		println("using old semantics")
	} else {
		println("using new semantics")
	}
}
% GOTOOLCHAIN=go1.21.0 go run x.go
using old semantics
% GOTOOLCHAIN=go1.22.0 go run x.go
using new semantics
% GOTOOLCHAIN=go1.22.0 go run -gcflags=-lang=go1.22 x.go
using old semantics
% 

@rsc
Copy link
Contributor

rsc commented Apr 5, 2024

CL 567435 in progress should fix this. The fix is to just make sure that cmd/go passes -lang to the compiler always.

I looked into changing what the compiler does when -lang is empty, but right now it intentionally ignores the //go:build lines to avoid downgrades, and for good reason (for example see GOROOT/src/internal/types/testdata/check/go1_xx_19.go). If we change the compiler, we risk breaking other uses of the compiler like Bazel. And the go command needs the logic anyway to help cmd/vet, so we might as well just make sure the go command always makes the decision.

@rsc rsc changed the title cmd/compile: "//go:build go1.xy" versions ignored when -lang is not set cmd/go: always pass -lang to cmd/compile Apr 5, 2024
@gopherbot
Copy link

Change https://go.dev/cl/567435 mentions this issue: cmd/go: set the GoVersion for files listed on the commandline

@samthanawalla samthanawalla self-assigned this Apr 15, 2024
@samthanawalla samthanawalla added FixPending Issues that have a fix which has not yet been reviewed or submitted. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Apr 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FixPending Issues that have a fix which has not yet been reviewed or submitted. GoCommand cmd/go
Projects
None yet
Development

No branches or pull requests

7 participants