--- /dev/null
+go mod tidy
+cp go.mod go.mod.orig
+
+# If there is no sensible *package* meaning for 'm/p', perhaps it should refer
+# to *module* m/p?
+# Today, it still seems to refer to the package.
+
+! go get -d m/p@v0.1.0
+stderr 'go get m/p@v0.1.0: module m/p@latest found \(v0.1.0, replaced by ./mp01\), but does not contain package m/p'
+cmp go.mod.orig go.mod
+
+
+# TODO(#37438): If we add v0.2.0 before this point, we end up (somehow!)
+# resolving m/p@v0.1.0 as *both* a module and a package.
+
+cp go.mod.orig go.mod
+go mod edit -replace=m@v0.2.0=./m02
+go mod edit -replace=m/p@v0.2.0=./mp02
+
+# The argument 'm/p' in 'go get m/p' refers to *package* m/p,
+# which is in module m.
+#
+# (It only refers to *module* m/p if there is no such package at the
+# requested version.)
+
+go get -d m/p@v0.2.0
+go list -m all
+stdout '^m v0.2.0 '
+stdout '^m/p v0.1.0 '
+
+# Repeating the above with module m/p already in the module graph does not
+# change its meaning.
+
+go get -d m/p@v0.2.0
+go list -m all
+stdout '^m v0.2.0 '
+stdout '^m/p v0.1.0 '
+
+
+# TODO(#37438): If we add v0.3.0 before this point, we get a totally bogus error
+# today, because 'go get' ends up attempting to resolve package 'm/p' without a
+# specific version and can't find it if module m no longer contains v0.3.0.
+
+cp go.mod.orig go.mod
+go mod edit -replace=m@v0.3.0=./m03
+go mod edit -replace=m/p@v0.3.0=./mp03
+
+! go get -d m/p@v0.2.0
+stderr 'go get m/p@v0.2.0: module m/p@latest found \(v0.3.0, replaced by ./mp03\), but does not contain package m/p$'
+
+# If there is no sensible package meaning for 'm/p', perhaps it should refer
+# to *module* m/p?
+# Today, it still seems to refer to the package.
+
+! go get -d m/p@v0.3.0
+stderr '^go get m/p@v0.3.0: module m/p@latest found \(v0\.3\.0, replaced by \./mp03\), but does not contain package m/p$'
+
+
+-- go.mod --
+module example.com
+
+go 1.16
+
+replace (
+ m v0.1.0 => ./m01
+ m/p v0.1.0 => ./mp01
+)
+-- m01/go.mod --
+module m
+
+go 1.16
+-- m01/README.txt --
+Module m at v0.3.0 does not yet contain package p.
+
+-- m02/go.mod --
+module m
+
+go 1.16
+
+require m/p v0.1.0
+-- m02/p/p.go --
+// Package p is present in module m, but not module m/p.
+package p
+
+-- m03/go.mod --
+module m
+
+go 1.16
+
+require m/p v0.1.0
+-- m03/README.txt --
+Module m at v0.3.0 no longer contains package p.
+
+-- mv2/go.mod --
+module m/v2
+
+go 1.16
+-- mv2/README.txt --
+This module is m/v2. It doesn't actually need to exist,
+but it explains how module m could plausibly exist
+and still contain package p at 'latest' even when module
+m/p also exists.
+
+-- mp01/go.mod --
+module m/p
+
+go 1.16
+-- mp01/README.txt --
+This module is m/p.
+Package m/p no longer exists.
+-- mp02/go.mod --
+module m/p
+
+go 1.16
+-- mp02/README.txt --
+This module is m/p.
+Package m/p no longer exists.
+-- mp03/go.mod --
+module m/p
+
+go 1.16
+-- mp03/README.txt --
+This module is m/p.
+Package m/p no longer exists.