-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: cmd/{go,cgo,compile}: change interpretation of relative //line directives #70478
Comments
Since, as you say, the change is not backward compatible, and since we actually tried a related change in 2018 and had to roll it back, I think that we need a |
Perhaps, though the related change was in the reverse direction, so was a clear regression in functionality for source tools based on go/scanner, whereas the proposed change should mostly affect the behavior of builds that fail, which by definition are exempt from compatibility. |
Wouldn’t it also affect the output of traceback, profiles, debuggers (unsure of this one?), etc? |
Yes, it would certainly be an observable change, but I suspect that very few existing tests of such tools rely on scenarios as complex and fragile as the specific outputs (file/line etc) of source generation tools, since they can change for all kinds of reasons. (In the specific case of cgo, we wouldn't expect any changes because the generator and consumer would change together.) I'm not opposed to a GODEBUG flag, but we should assess whether one is needed before adding one. |
Background: generated Go source files may contain //line directives that relate each line of Go source to the line of some other file from which it was generated. If the file named by the line directive is a relative path, cmd/compile currently interprets it like any other relative path, that is, relative to its own os.Getwd. This demands that the tool that generated the //line directive has the same working directory as the compiler (e.g. GOROOT/src), or that it creates the line directive in anticipation of the consuming process having (say) GOROOT/src as its working directory.
By contrast, go/scanner takes a different approach: it interprets relative line directives relative to the scanned file's directory. So, if it encounters the line directive
//line a.yacc:1
in a file nameda/a.go
, the relative line directive is resolved asa/a.yacc
. (In March 2018 go/scanner was changed to resemble the compiler in CL 100235, but this was reverted in August 2018 by CL 127658.)The difference in behavior is easily observed by introducing a dummy line directive with a compiler error into an arbitrary Go source file. In this case, we'll append a relative reference from gopls/main.go to its README.md file:
When we build the package, the error message names a non-existent file:
When we use tools based on go/scanner, the error message names the correct file:
This is true even when we run the same commands from a different directory. Again,
go build
names the non-existent file, and go/scanner names the correct file:Proposal: The compiler's scanner should interpret relative line directives relative to the directory of the scanned file, and this behavior should be documented at https://pkg.go.dev/cmd/compile#hdr-Compiler_Directives.
This may require changes to the line directives emitted by cgo and other tools (including unparam and unconvert, whatever they are).
Arguably, this is an incompatible change, but we notice that more often than not, when published Go modules use relative line directives, they already follow the proposed discipline.
See also:
@griesemer @ianlancetaylor @findleyr @timothy-king
The text was updated successfully, but these errors were encountered: