cmd/go: include module path and version in cache key with -trimpath

When -trimpath is used, packages built from the module cache still
have debug into that contains the module path and version. Only the
module cache directory is stripped.

With this CL, we now include the module path and version in the cache
key for build actions.

Fixes #35412

Change-Id: I1956592d0d86fcea2cca7c5fc8957e83543d6aa2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207317
Run-TryBot: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
index c8849b4..0287af7 100644
--- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go
@@ -206,8 +206,12 @@
 	// The compiler hides the exact value of $GOROOT
 	// when building things in GOROOT.
 	// Assume b.WorkDir is being trimmed properly.
+	// When -trimpath is used with a package built from the module cache,
+	// use the module path and version instead of the directory.
 	if !p.Goroot && !cfg.BuildTrimpath && !strings.HasPrefix(p.Dir, b.WorkDir) {
 		fmt.Fprintf(h, "dir %s\n", p.Dir)
+	} else if cfg.BuildTrimpath && p.Module != nil {
+		fmt.Fprintf(h, "module %s@%s\n", p.Module.Path, p.Module.Version)
 	}
 	fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch)
 	fmt.Fprintf(h, "import %q\n", p.ImportPath)
diff --git a/src/cmd/go/testdata/mod/example.com_stack_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_stack_v1.0.0.txt
new file mode 100644
index 0000000..787b7ae
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_stack_v1.0.0.txt
@@ -0,0 +1,18 @@
+Module with a function that prints file name for the top stack frame.
+Different versions of this module are identical, but they should return
+different file names with -trimpath.
+-- .mod --
+module example.com/stack
+
+go 1.14
+-- .info --
+{"Version":"v1.0.0"}
+-- stack.go --
+package stack
+
+import "runtime"
+
+func TopFile() string {
+	_, file, _, _ := runtime.Caller(0)
+	return file
+}
diff --git a/src/cmd/go/testdata/mod/example.com_stack_v1.0.1.txt b/src/cmd/go/testdata/mod/example.com_stack_v1.0.1.txt
new file mode 100644
index 0000000..c715dd2
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_stack_v1.0.1.txt
@@ -0,0 +1,18 @@
+Module with a function that prints file name for the top stack frame.
+Different versions of this module are identical, but they should return
+different file names with -trimpath.
+-- .mod --
+module example.com/stack
+
+go 1.14
+-- .info --
+{"Version":"v1.0.1"}
+-- stack.go --
+package stack
+
+import "runtime"
+
+func TopFile() string {
+	_, file, _, _ := runtime.Caller(0)
+	return file
+}
diff --git a/src/cmd/go/testdata/script/build_cache_trimpath.txt b/src/cmd/go/testdata/script/build_cache_trimpath.txt
index 39367ae..9a4b9d7 100644
--- a/src/cmd/go/testdata/script/build_cache_trimpath.txt
+++ b/src/cmd/go/testdata/script/build_cache_trimpath.txt
@@ -1,3 +1,4 @@
+[short] skip
 env GO111MODULE=on
 
 # Set up fresh GOCACHE.
@@ -12,9 +13,35 @@
 stderr '(compile|gccgo)( |\.exe)'
 stderr 'link( |\.exe)'
 
+# Two distinct versions of the same module with identical content should
+# still be cached separately.
+# Verifies golang.org/issue/35412.
+go get -d example.com/stack@v1.0.0
+go run -trimpath printstack.go
+stdout '^example.com/stack@v1.0.0/stack.go$'
+go get -d example.com/stack@v1.0.1
+go run -trimpath printstack.go
+stdout '^example.com/stack@v1.0.1/stack.go$'
+
 -- $WORK/hello.go --
 package main
 func main() { println("hello") }
 
+-- $WORK/printstack.go --
+// +build ignore
+
+package main
+
+import (
+	"fmt"
+
+	"example.com/stack"
+)
+
+func main() {
+	fmt.Println(stack.TopFile())
+}
 -- $WORK/go.mod --
 module m
+
+go 1.14