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: missing version diagnostic when a package in the main module imports a package from a newer release #48966

Closed
andig opened this issue Oct 14, 2021 · 10 comments
Labels
FrozenDueToAge GoCommand cmd/go help wanted NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@andig
Copy link
Contributor

andig commented Oct 14, 2021

Given

module example.com/M

go 1.16

and using embed as part of that module, I'm experiencing a lot of user's questions where compilation fails due to go versions below 1.16. Having declared dependency on go1.16 syntax/libraries as part of go.mod it would be nice if the compiler would fail if the module version of the main module or it's dependencies are not met during build. It could be optional behaviour behind a flag.

I realise this might cause breakage for modules who's authors use the highes available go version as part of their go.mod to be "compatible", but that approach seems flawed anyway.

@bcmills
Copy link
Contributor

bcmills commented Oct 14, 2021

What kind of errors are your users reporting? When the build fails, they should be getting an explicit notice about the version mismatch already.

@bcmills
Copy link
Contributor

bcmills commented Oct 14, 2021

(Also compare #46136.)

@andig
Copy link
Contributor Author

andig commented Oct 14, 2021

What kind of errors are your users reporting? When the build fails, they should be getting an explicit notice about the version mismatch already.

From evcc-io/evcc#1303:

pi@evcc:/opt/repos/evcc/evcc $ go build ./...
build github.com/andig/evcc: cannot find module for path embed 

For an end user that tries to self-compile its impossible to relate this error in a mismatching go version.

@bcmills
Copy link
Contributor

bcmills commented Oct 14, 2021

That report is from

go version go1.11.6 linux/arm

That version of Go is way out of date: per the Go project's release policy, the current supported versions of the toolchain are 1.16.9 and 1.17.2.

Any change we would make at this point would only affect 1.18 and later, and I posit that the supported versions of the toolchain already produce a much more useful diagnostic in this case.

@bcmills
Copy link
Contributor

bcmills commented Oct 14, 2021

Hmm... It is the case that go1.15.15 (the last release that did not include the embed package) still produces a pretty useless error here:

/tmp/evcc$ go1.15.15 build ./...
main.go:4:2: package embed is not in GOROOT (/usr/local/google/home/bcmills/sdk/go1.15/src/embed)
/usr/local/google/home/bcmills/pkg/mod/github.com/evcc-io/eebus@v0.0.0-20211004203943-949a5847f2ea/cert/cert.go:16:2: package io/fs is not in GOROOT (/usr/local/google/home/bcmills/sdk/go1.15/src/io/fs)

It looks like the failure in module resolution is before the failure due to the Go version.

And if we construct a similar situation with some new 1.18 package using Go 1.17.2, we still get a bad error message:

$ go1.17.2 build .
main.go:3:8: package constraints is not in GOROOT (/usr/local/google/home/bcmills/sdk/go1.17.2/src/constraints)

-- go.mod --
module example

go 1.18
-- main.go --
package main

import _ "constraints"

func main() {}

So there is a bug to be fixed here — but it's just a bug, it doesn't need to go through the proposal process.

@bcmills bcmills changed the title go/build: proposal to fail if go.mod version is higher than go compiler version cmd/go: poor diagnostic when the main module specifies a newer Go version and imports a newly-added package Oct 14, 2021
@bcmills bcmills changed the title cmd/go: poor diagnostic when the main module specifies a newer Go version and imports a newly-added package cmd/go: missing version diagnostic when the main module specifies a newer Go version and imports a newly-added package Oct 14, 2021
@bcmills bcmills changed the title cmd/go: missing version diagnostic when the main module specifies a newer Go version and imports a newly-added package cmd/go: missing version diagnostic when a package in the main module imports a package from a newer release Oct 14, 2021
@bcmills bcmills added GoCommand cmd/go help wanted NeedsFix The path to resolution is known, but the work has not been done. labels Oct 14, 2021
@bcmills bcmills added this to the Backlog milestone Oct 14, 2021
@andig
Copy link
Contributor Author

andig commented Oct 26, 2021

Note https://github.com/theckman/goconstraint/ for a go-only compile time solution.

@mzacho
Copy link

mzacho commented Jan 10, 2022

I'd like to look into this issue - @bcmills do you have some pointers on how to fix it?

@bcmills
Copy link
Contributor

bcmills commented Jan 10, 2022

@zacho314, the error message that we see is from an ImportMissingError:
https://cs.opensource.google/go/go/+/master:src/cmd/go/internal/modload/import.go;l=54-56;drc=master

Generally when we see an ImportMissingError we attribute that to the package being imported, but in this case we want to also attribute the error to the importing package, since we can't tell whether the error is due to a missing standard-library package or a missing package to be provided by a replace directive.

I suspect that the point where we're reporting the error today is here:
https://cs.opensource.google/go/go/+/master:src/cmd/go/internal/modload/load.go;l=1205;drc=master

What we need to propagate this error correctly is something like:
For each package pkg, if all of:

  • pkg imports a package with an ImportMissingError for which isStd == true
  • pkg.mod specifies a higher Go version than the current version,
  • and pkg.err is nil,
    then set pkg.err to an error that indicates the mismatched version.

We already have a “for each package pkg” loop that also iterates over imports today in (*loader).buildStacks; that might be a decent place to put the above logic as well.

@lazerkat
Copy link
Contributor

I plan on looking into this if @mzacho isn't actively working on it.

@gopherbot
Copy link

Change https://go.dev/cl/432075 mentions this issue: modload: provide a clearer compiler error for standard library packages from newer releases

romaindoumenc pushed a commit to TroutSoftware/go that referenced this issue Nov 3, 2022
…ewer releases

An older version of go compiling a main module that references a
standard library package from a newer release (e.g. net/netip added in
go 1.18) currently produces a confusing error message. This changes adds
a new error message including go version diagnostics.

Fixes golang#48966

Change-Id: I1e8319dafcf1f67d1b1ca869fe84190c3b3f3c3e
Reviewed-on: https://go-review.googlesource.com/c/go/+/432075
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
@golang golang locked and limited conversation to collaborators Oct 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge GoCommand cmd/go help wanted NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants