What version of Go are you using (go version)?

$ go version
go version go1.16beta1 darwin/amd64
go version go1.15.6 darwin/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/jayconrod/Library/Caches/go-build"
GOENV="/Users/jayconrod/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/jayconrod/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/jayconrod/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/go/installed"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/go/installed/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16beta1"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/jayconrod/Code/test/m/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/rq/x0692kqj6ml8cvrhcqh5bswc008xj1/T/go-build3064706002=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Create three local modules: M (main module, requiring and replacing the other two), A (module in a directory outside M), and B (module in a subdirectory of A).

Attempt to list a package in B using a relative or absolute file path.

cd m
go list ../a   # works
go list ../a/b # fails

-- m/go.mod --
module example.com/m

go 1.15

require (
    example.com/a v0.0.0
    example.com/b v0.0.0
)

replace (
    example.com/a v0.0.0 => ../a
    example.com/b v0.0.0 => ../a/b
)
-- a/go.mod --
module example.com/a
-- a/a.go --
package a
-- a/b/go.mod --
module example.com/b

go 1.15
-- a/b/b.go --
package b

What did you expect to see?

Package name is printed successfully:

example.com/a/b

What did you see instead?

$ go list ../a/b
no required module provides package example.com/a/b; try 'go get -d example.com/a/b' to add it

Comment From: bcmills

This is because ../a/b is interpreted as a relative package path rather than a relative file path, I think.

What should happen in the analogous situation where the module is located at ./a/b and the user runs go list ./a/b? (https://play.golang.org/p/C3qTwKrW2vJ) Should that also be interpreted as a file path?

What if the path includes a ... wildcard, such as ./a/b/... or ./a/... or ../a/... or ../a/b/...?

Comment From: jayconrod

../a/b is being interpreted as a file path; the problem is with file paths into nested replacement modules in general. I get the same error with an absolute path.

Listing a package in example.com/a works:

$ go list ../a
example.com/a

The wildcard causes a different error, whether or not the module is in a nested replacement. This might be WAI though.

$ go list ../a/...
pattern ../a/...: directory /Users/jayconrod/Code/test/a is outside module root (/Users/jayconrod/Code/test/m)
$ go list ../a/b/...
pattern ../a/b/...: directory /Users/jayconrod/Code/test/a/b is outside module root (/Users/jayconrod/Code/test/m)

Comment From: jayconrod

The context for this is this golang-nuts thread by the way.

Comment From: ianlancetaylor

This is in the Go1.18 milestone. Is it likely to happen for 1.18? Thanks.

Comment From: ianlancetaylor

@bcmills This is in the 1.18 milestone; time to move to 1.19? Thanks.

Comment From: ianlancetaylor

@bcmills @matloob This issue is marked for 1.19. It's just been rolling forward in milestones. Should it move to Backlog?