Skip to content

Commit

Permalink
cmd/go/internal/modload: in updateLazyRoots, do not require the main …
Browse files Browse the repository at this point in the history
…module explicitly

Fixes #46078

Change-Id: I8044dac717459f1eeae1d8381a6503f22f9f51ff
Reviewed-on: https://go-review.googlesource.com/c/go/+/319009
Trust: Bryan C. Mills <[email protected]>
Reviewed-by: Jay Conrod <[email protected]>
  • Loading branch information
Bryan C. Mills committed May 12, 2021
1 parent f93b951 commit 6db7480
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/cmd/go/internal/modload/buildlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,8 @@ func updateLazyRoots(ctx context.Context, direct map[string]bool, rs *Requiremen

roots = make([]module.Version, 0, len(rs.rootModules))
rootsUpgraded = false
inRootPaths := make(map[string]bool, len(rs.rootModules))
inRootPaths := make(map[string]bool, len(rs.rootModules)+1)
inRootPaths[Target.Path] = true
for _, m := range rs.rootModules {
if inRootPaths[m.Path] {
// This root specifies a redundant path. We already retained the
Expand Down
71 changes: 71 additions & 0 deletions src/cmd/go/testdata/script/mod_tidy_lazy_self.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Regression test for https://golang.org/issue/46078:
# 'go mod tidy' should not panic if the main module initially
# requires an older version of itself.


# A module that explicitly requires an older version of itself should be
# rejected as inconsistent: we enforce that every explicit requirement is the
# selected version of its module path, but the selected version of the main
# module is always itself — not some explicit version.

! go list -m all
stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$'


# The suggested 'go mod tidy' command should succeed (not crash).

go mod tidy


# We prune out redundant roots very early on in module loading, and at that
# point the indirect requirement on example.net/x v0.1.0 appears to be
# irrelevant. It should be pruned out; when the import of "example.net/x" is
# later resolved, it should resolve at the latest version (v0.2.0), not the
# version implied by the (former) misleading requirement on the older version of
# the main module.

cmp go.mod go.mod.tidy


-- go.mod --
module golang.org/issue/46078

go 1.17

replace (
example.net/x v0.1.0 => ./x
example.net/x v0.2.0 => ./x
golang.org/issue/46078 v0.1.0 => ./old
)

require golang.org/issue/46078 v0.1.0
-- go.mod.tidy --
module golang.org/issue/46078

go 1.17

replace (
example.net/x v0.1.0 => ./x
example.net/x v0.2.0 => ./x
golang.org/issue/46078 v0.1.0 => ./old
)

require example.net/x v0.2.0
-- issue46078/issue.go --
package issue46078

import _ "example.net/x"

-- old/go.mod --
module golang.org/issue/46078

go 1.17

require example.net/x v0.1.0

-- x/go.mod --
module example.net/x

go 1.17
-- x/x.go --
package x

0 comments on commit 6db7480

Please sign in to comment.