diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go index 61cbdf2c543264..8c34a933d05262 100644 --- a/src/cmd/go/internal/modload/init.go +++ b/src/cmd/go/internal/modload/init.go @@ -1012,6 +1012,18 @@ func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileInd if prev, dup := i.replace[r.Old]; dup && prev != r.New { base.Fatalf("go: conflicting replacements for %v:\n\t%v\n\t%v", r.Old, prev, r.New) } + + if r.Old.Path == modFile.Module.Mod.Path && r.Old.Version == "" { + base.Fatalf("go: %s:%d: the main module (%s) cannot be replaced", + modFile.Syntax.Name, r.Syntax.Start.Line, modFile.Module.Mod.Path) + } + + if modfile.IsDirectoryPath(r.New.Path) && HasModRoot() && ((search.IsRelativePath(r.New.Path) && filepath.Join(ModRoot(), r.New.Path) == ModRoot()) || + search.InDir(r.New.Path, ModRoot()) == ".") { + base.Fatalf("go: %s:%d: the main module root directory (%s) cannot be a replacement for another module", + modFile.Syntax.Name, r.Syntax.Start.Line, modFile.Module.Mod.Path) + } + i.replace[r.Old] = r.New } diff --git a/src/cmd/go/testdata/script/mod_replace_main.txt b/src/cmd/go/testdata/script/mod_replace_main.txt new file mode 100644 index 00000000000000..0a236067d48add --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace_main.txt @@ -0,0 +1,38 @@ +env GO111MODULE=on +[short] skip + +cd fail1 +! go list all +stderr 'go: \$WORK\/gopath\/src\/fail1\/go\.mod:3: the main module root directory \(example\.com\/m\) cannot be a replacement for another module' + +cd ../fail2 +! go list all +stderr 'go: \$WORK\/gopath\/src\/fail2\/go\.mod:3: the main module \(example\.com\/m\) cannot be replaced' + +# Different module version can be replaced +cd ../success +go list all +stdout 'example.com/m' + +-- fail1/go.mod -- +module example.com/m + +replace example.com/m2 => ./. + +-- fail2/go.mod -- +module example.com/m + +replace example.com/m => example.com/m v1.1.1 + +-- success/go.mod -- +module example.com/m + +replace example.com/m v1.1.1 => example.com/m v1.1.2 + +-- fork/go.mod -- +module example.com/m + +-- success/m.go -- +package main + +func main() {} \ No newline at end of file