mirror of
https://github.com/golang/go
synced 2024-09-04 15:34:21 +00:00
Merge "[dev.typeparams] all: merge master (37f9a8f
) into dev.typeparams" into dev.typeparams
This commit is contained in:
commit
373ca3a846
|
@ -187,6 +187,13 @@ Do not send CLs removing the interior tags from such phrases.
|
||||||
features.
|
features.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/46366 -->
|
||||||
|
The <code>go</code> <code>mod</code> <code>graph</code> subcommand also
|
||||||
|
supports the <code>-go</code> flag, which causes it to report the graph as
|
||||||
|
seen by the indicated Go version, showing dependencies that may otherwise be
|
||||||
|
pruned out by lazy loading.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h4 id="module-deprecation-comments">Module deprecation comments</h4>
|
<h4 id="module-deprecation-comments">Module deprecation comments</h4>
|
||||||
|
|
||||||
<p><!-- golang.org/issue/40357 -->
|
<p><!-- golang.org/issue/40357 -->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<!--{
|
<!--{
|
||||||
"Title": "The Go Programming Language Specification",
|
"Title": "The Go Programming Language Specification",
|
||||||
"Subtitle": "Version of Jun 2, 2021",
|
"Subtitle": "Version of Jun 22, 2021",
|
||||||
"Path": "/ref/spec"
|
"Path": "/ref/spec"
|
||||||
}-->
|
}-->
|
||||||
|
|
||||||
|
@ -4670,7 +4670,7 @@ The following built-in functions are not permitted in statement context:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
append cap complex imag len make new real
|
append cap complex imag len make new real
|
||||||
unsafe.Alignof unsafe.Offsetof unsafe.Sizeof
|
unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
|
@ -3106,7 +3106,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
|
||||||
arrlen := s.constInt(types.Types[types.TINT], n.Type().Elem().NumElem())
|
arrlen := s.constInt(types.Types[types.TINT], n.Type().Elem().NumElem())
|
||||||
cap := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], v)
|
cap := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], v)
|
||||||
s.boundsCheck(arrlen, cap, ssa.BoundsConvert, false)
|
s.boundsCheck(arrlen, cap, ssa.BoundsConvert, false)
|
||||||
return s.newValue1(ssa.OpSlicePtrUnchecked, types.Types[types.TINT], v)
|
return s.newValue1(ssa.OpSlicePtrUnchecked, n.Type(), v)
|
||||||
|
|
||||||
case ir.OCALLFUNC:
|
case ir.OCALLFUNC:
|
||||||
n := n.(*ir.CallExpr)
|
n := n.(*ir.CallExpr)
|
||||||
|
|
|
@ -1186,13 +1186,17 @@
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
//
|
//
|
||||||
// go mod graph
|
// go mod graph [-go=version]
|
||||||
//
|
//
|
||||||
// Graph prints the module requirement graph (with replacements applied)
|
// Graph prints the module requirement graph (with replacements applied)
|
||||||
// in text form. Each line in the output has two space-separated fields: a module
|
// in text form. Each line in the output has two space-separated fields: a module
|
||||||
// and one of its requirements. Each module is identified as a string of the form
|
// and one of its requirements. Each module is identified as a string of the form
|
||||||
// path@version, except for the main module, which has no @version suffix.
|
// path@version, except for the main module, which has no @version suffix.
|
||||||
//
|
//
|
||||||
|
// The -go flag causes graph to report the module graph as loaded by by the
|
||||||
|
// given Go version, instead of the version indicated by the 'go' directive
|
||||||
|
// in the go.mod file.
|
||||||
|
//
|
||||||
// See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
|
// See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -1887,6 +1891,9 @@
|
||||||
// GOMIPS64
|
// GOMIPS64
|
||||||
// For GOARCH=mips64{,le}, whether to use floating point instructions.
|
// For GOARCH=mips64{,le}, whether to use floating point instructions.
|
||||||
// Valid values are hardfloat (default), softfloat.
|
// Valid values are hardfloat (default), softfloat.
|
||||||
|
// GOPPC64
|
||||||
|
// For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
|
||||||
|
// Valid values are power8 (default), power9.
|
||||||
// GOWASM
|
// GOWASM
|
||||||
// For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
|
// For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
|
||||||
// Valid values are satconv, signext.
|
// Valid values are satconv, signext.
|
||||||
|
|
|
@ -77,6 +77,14 @@ func defaultContext() build.Context {
|
||||||
ctxt.GOOS = envOr("GOOS", ctxt.GOOS)
|
ctxt.GOOS = envOr("GOOS", ctxt.GOOS)
|
||||||
ctxt.GOARCH = envOr("GOARCH", ctxt.GOARCH)
|
ctxt.GOARCH = envOr("GOARCH", ctxt.GOARCH)
|
||||||
|
|
||||||
|
// The experiments flags are based on GOARCH, so they may
|
||||||
|
// need to change. TODO: This should be cleaned up.
|
||||||
|
buildcfg.UpdateExperiments(ctxt.GOARCH)
|
||||||
|
ctxt.ToolTags = nil
|
||||||
|
for _, exp := range buildcfg.EnabledExperiments() {
|
||||||
|
ctxt.ToolTags = append(ctxt.ToolTags, "goexperiment."+exp)
|
||||||
|
}
|
||||||
|
|
||||||
// The go/build rule for whether cgo is enabled is:
|
// The go/build rule for whether cgo is enabled is:
|
||||||
// 1. If $CGO_ENABLED is set, respect it.
|
// 1. If $CGO_ENABLED is set, respect it.
|
||||||
// 2. Otherwise, if this is a cross-compile, disable cgo.
|
// 2. Otherwise, if this is a cross-compile, disable cgo.
|
||||||
|
|
|
@ -598,6 +598,9 @@ Architecture-specific environment variables:
|
||||||
GOMIPS64
|
GOMIPS64
|
||||||
For GOARCH=mips64{,le}, whether to use floating point instructions.
|
For GOARCH=mips64{,le}, whether to use floating point instructions.
|
||||||
Valid values are hardfloat (default), softfloat.
|
Valid values are hardfloat (default), softfloat.
|
||||||
|
GOPPC64
|
||||||
|
For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
|
||||||
|
Valid values are power8 (default), power9.
|
||||||
GOWASM
|
GOWASM
|
||||||
For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
|
For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
|
||||||
Valid values are satconv, signext.
|
Valid values are satconv, signext.
|
||||||
|
|
|
@ -116,7 +116,7 @@ func TestPackagesAndErrors(ctx context.Context, opts PackageOpts, p *Package, co
|
||||||
// Can't change that code, because that code is only for loading the
|
// Can't change that code, because that code is only for loading the
|
||||||
// non-test copy of a package.
|
// non-test copy of a package.
|
||||||
ptestErr = &PackageError{
|
ptestErr = &PackageError{
|
||||||
ImportStack: testImportStack(stk[0], p1, p.ImportPath),
|
ImportStack: importCycleStack(p1, p.ImportPath),
|
||||||
Err: errors.New("import cycle not allowed in test"),
|
Err: errors.New("import cycle not allowed in test"),
|
||||||
IsImportCycle: true,
|
IsImportCycle: true,
|
||||||
}
|
}
|
||||||
|
@ -375,22 +375,44 @@ func TestPackagesAndErrors(ctx context.Context, opts PackageOpts, p *Package, co
|
||||||
return pmain, ptest, pxtest
|
return pmain, ptest, pxtest
|
||||||
}
|
}
|
||||||
|
|
||||||
func testImportStack(top string, p *Package, target string) []string {
|
// importCycleStack returns an import stack from p to the package whose import
|
||||||
stk := []string{top, p.ImportPath}
|
// path is target.
|
||||||
Search:
|
func importCycleStack(p *Package, target string) []string {
|
||||||
for p.ImportPath != target {
|
// importerOf maps each import path to its importer nearest to p.
|
||||||
for _, p1 := range p.Internal.Imports {
|
importerOf := map[string]string{p.ImportPath: ""}
|
||||||
if p1.ImportPath == target || str.Contains(p1.Deps, target) {
|
|
||||||
stk = append(stk, p1.ImportPath)
|
// q is a breadth-first queue of packages to search for target.
|
||||||
p = p1
|
// Every package added to q has a corresponding entry in pathTo.
|
||||||
continue Search
|
//
|
||||||
|
// We search breadth-first for two reasons:
|
||||||
|
//
|
||||||
|
// 1. We want to report the shortest cycle.
|
||||||
|
//
|
||||||
|
// 2. If p contains multiple cycles, the first cycle we encounter might not
|
||||||
|
// contain target. To ensure termination, we have to break all cycles
|
||||||
|
// other than the first.
|
||||||
|
q := []*Package{p}
|
||||||
|
|
||||||
|
for len(q) > 0 {
|
||||||
|
p := q[0]
|
||||||
|
q = q[1:]
|
||||||
|
if path := p.ImportPath; path == target {
|
||||||
|
var stk []string
|
||||||
|
for path != "" {
|
||||||
|
stk = append(stk, path)
|
||||||
|
path = importerOf[path]
|
||||||
|
}
|
||||||
|
return stk
|
||||||
|
}
|
||||||
|
for _, dep := range p.Internal.Imports {
|
||||||
|
if _, ok := importerOf[dep.ImportPath]; !ok {
|
||||||
|
importerOf[dep.ImportPath] = p.ImportPath
|
||||||
|
q = append(q, dep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Can't happen, but in case it does...
|
|
||||||
stk = append(stk, "<lost path to cycle>")
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
return stk
|
|
||||||
|
panic("lost path to cycle")
|
||||||
}
|
}
|
||||||
|
|
||||||
// recompileForTest copies and replaces certain packages in pmain's dependency
|
// recompileForTest copies and replaces certain packages in pmain's dependency
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdGraph = &base.Command{
|
var cmdGraph = &base.Command{
|
||||||
UsageLine: "go mod graph",
|
UsageLine: "go mod graph [-go=version]",
|
||||||
Short: "print module requirement graph",
|
Short: "print module requirement graph",
|
||||||
Long: `
|
Long: `
|
||||||
Graph prints the module requirement graph (with replacements applied)
|
Graph prints the module requirement graph (with replacements applied)
|
||||||
|
@ -26,12 +26,21 @@ in text form. Each line in the output has two space-separated fields: a module
|
||||||
and one of its requirements. Each module is identified as a string of the form
|
and one of its requirements. Each module is identified as a string of the form
|
||||||
path@version, except for the main module, which has no @version suffix.
|
path@version, except for the main module, which has no @version suffix.
|
||||||
|
|
||||||
|
The -go flag causes graph to report the module graph as loaded by by the
|
||||||
|
given Go version, instead of the version indicated by the 'go' directive
|
||||||
|
in the go.mod file.
|
||||||
|
|
||||||
See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
|
See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
|
||||||
`,
|
`,
|
||||||
Run: runGraph,
|
Run: runGraph,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
graphGo goVersionFlag
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
cmdGraph.Flag.Var(&graphGo, "go", "")
|
||||||
base.AddModCommonFlags(&cmdGraph.Flag)
|
base.AddModCommonFlags(&cmdGraph.Flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +50,7 @@ func runGraph(ctx context.Context, cmd *base.Command, args []string) {
|
||||||
}
|
}
|
||||||
modload.ForceUseModules = true
|
modload.ForceUseModules = true
|
||||||
modload.RootMode = modload.NeedRoot
|
modload.RootMode = modload.NeedRoot
|
||||||
mg := modload.LoadModGraph(ctx)
|
mg := modload.LoadModGraph(ctx, graphGo.String())
|
||||||
|
|
||||||
w := bufio.NewWriter(os.Stdout)
|
w := bufio.NewWriter(os.Stdout)
|
||||||
defer w.Flush()
|
defer w.Flush()
|
||||||
|
|
|
@ -54,7 +54,8 @@ func runVerify(ctx context.Context, cmd *base.Command, args []string) {
|
||||||
sem := make(chan token, runtime.GOMAXPROCS(0))
|
sem := make(chan token, runtime.GOMAXPROCS(0))
|
||||||
|
|
||||||
// Use a slice of result channels, so that the output is deterministic.
|
// Use a slice of result channels, so that the output is deterministic.
|
||||||
mods := modload.LoadModGraph(ctx).BuildList()[1:]
|
const defaultGoVersion = ""
|
||||||
|
mods := modload.LoadModGraph(ctx, defaultGoVersion).BuildList()[1:]
|
||||||
errsChans := make([]<-chan []error, len(mods))
|
errsChans := make([]<-chan []error, len(mods))
|
||||||
|
|
||||||
for i, mod := range mods {
|
for i, mod := range mods {
|
||||||
|
|
|
@ -506,7 +506,8 @@ type versionReason struct {
|
||||||
func newResolver(ctx context.Context, queries []*query) *resolver {
|
func newResolver(ctx context.Context, queries []*query) *resolver {
|
||||||
// LoadModGraph also sets modload.Target, which is needed by various resolver
|
// LoadModGraph also sets modload.Target, which is needed by various resolver
|
||||||
// methods.
|
// methods.
|
||||||
mg := modload.LoadModGraph(ctx)
|
const defaultGoVersion = ""
|
||||||
|
mg := modload.LoadModGraph(ctx, defaultGoVersion)
|
||||||
|
|
||||||
buildList := mg.BuildList()
|
buildList := mg.BuildList()
|
||||||
initialVersion := make(map[string]string, len(buildList))
|
initialVersion := make(map[string]string, len(buildList))
|
||||||
|
@ -1803,7 +1804,8 @@ func (r *resolver) updateBuildList(ctx context.Context, additions []module.Versi
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
r.buildList = modload.LoadModGraph(ctx).BuildList()
|
const defaultGoVersion = ""
|
||||||
|
r.buildList = modload.LoadModGraph(ctx, defaultGoVersion).BuildList()
|
||||||
r.buildListVersion = make(map[string]string, len(r.buildList))
|
r.buildListVersion = make(map[string]string, len(r.buildList))
|
||||||
for _, m := range r.buildList {
|
for _, m := range r.buildList {
|
||||||
r.buildListVersion[m.Path] = m.Version
|
r.buildListVersion[m.Path] = m.Version
|
||||||
|
|
|
@ -403,11 +403,33 @@ func (mg *ModuleGraph) allRootsSelected() bool {
|
||||||
// LoadModGraph loads and returns the graph of module dependencies of the main module,
|
// LoadModGraph loads and returns the graph of module dependencies of the main module,
|
||||||
// without loading any packages.
|
// without loading any packages.
|
||||||
//
|
//
|
||||||
|
// If the goVersion string is non-empty, the returned graph is the graph
|
||||||
|
// as interpreted by the given Go version (instead of the version indicated
|
||||||
|
// in the go.mod file).
|
||||||
|
//
|
||||||
// Modules are loaded automatically (and lazily) in LoadPackages:
|
// Modules are loaded automatically (and lazily) in LoadPackages:
|
||||||
// LoadModGraph need only be called if LoadPackages is not,
|
// LoadModGraph need only be called if LoadPackages is not,
|
||||||
// typically in commands that care about modules but no particular package.
|
// typically in commands that care about modules but no particular package.
|
||||||
func LoadModGraph(ctx context.Context) *ModuleGraph {
|
func LoadModGraph(ctx context.Context, goVersion string) *ModuleGraph {
|
||||||
rs, mg, err := expandGraph(ctx, LoadModFile(ctx))
|
rs := LoadModFile(ctx)
|
||||||
|
|
||||||
|
if goVersion != "" {
|
||||||
|
depth := modDepthFromGoVersion(goVersion)
|
||||||
|
if depth == eager && rs.depth != eager {
|
||||||
|
// Use newRequirements instead of convertDepth because convertDepth
|
||||||
|
// also updates roots; here, we want to report the unmodified roots
|
||||||
|
// even though they may seem inconsistent.
|
||||||
|
rs = newRequirements(eager, rs.rootModules, rs.direct)
|
||||||
|
}
|
||||||
|
|
||||||
|
mg, err := rs.Graph(ctx)
|
||||||
|
if err != nil {
|
||||||
|
base.Fatalf("go: %v", err)
|
||||||
|
}
|
||||||
|
return mg
|
||||||
|
}
|
||||||
|
|
||||||
|
rs, mg, err := expandGraph(ctx, rs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Fatalf("go: %v", err)
|
base.Fatalf("go: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -428,6 +428,15 @@ func queryImport(ctx context.Context, path string, rs *Requirements) (module.Ver
|
||||||
mv = module.ZeroPseudoVersion("v0")
|
mv = module.ZeroPseudoVersion("v0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mg, err := rs.Graph(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return module.Version{}, err
|
||||||
|
}
|
||||||
|
if cmpVersion(mg.Selected(mp), mv) >= 0 {
|
||||||
|
// We can't resolve the import by adding mp@mv to the module graph,
|
||||||
|
// because the selected version of mp is already at least mv.
|
||||||
|
continue
|
||||||
|
}
|
||||||
mods = append(mods, module.Version{Path: mp, Version: mv})
|
mods = append(mods, module.Version{Path: mp, Version: mv})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
src/cmd/go/testdata/script/env_cross_build.txt
vendored
Normal file
29
src/cmd/go/testdata/script/env_cross_build.txt
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Test that the corect default GOEXPERIMENT is used when cross
|
||||||
|
# building with GOENV (#46815).
|
||||||
|
|
||||||
|
# Unset variables set by the TestScript harness. Users typically won't
|
||||||
|
# explicitly configure these, and #46815 doesn't repro if they are.
|
||||||
|
env GOOS=
|
||||||
|
env GOARCH=
|
||||||
|
env GOEXPERIMENT=
|
||||||
|
|
||||||
|
env GOENV=windows-amd64
|
||||||
|
go build internal/abi
|
||||||
|
|
||||||
|
env GOENV=ios-arm64
|
||||||
|
go build internal/abi
|
||||||
|
|
||||||
|
env GOENV=linux-mips
|
||||||
|
go build internal/abi
|
||||||
|
|
||||||
|
-- windows-amd64 --
|
||||||
|
GOOS=windows
|
||||||
|
GOARCH=amd64
|
||||||
|
|
||||||
|
-- ios-arm64 --
|
||||||
|
GOOS=ios
|
||||||
|
GOARCH=arm64
|
||||||
|
|
||||||
|
-- linux-mips --
|
||||||
|
GOOS=linux
|
||||||
|
GOARCH=mips
|
101
src/cmd/go/testdata/script/mod_graph_version.txt
vendored
Normal file
101
src/cmd/go/testdata/script/mod_graph_version.txt
vendored
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
# For this module, Go 1.17 prunes out a (transitive and otherwise-irrelevant)
|
||||||
|
# requirement on a retracted higher version of a dependency.
|
||||||
|
# However, when Go 1.16 reads the same requirements from the go.mod file,
|
||||||
|
# it does not prune out that requirement, and selects the retracted version.
|
||||||
|
#
|
||||||
|
# The Go 1.16 module graph looks like:
|
||||||
|
#
|
||||||
|
# m ---- lazy v0.1.0 ---- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible
|
||||||
|
# | |
|
||||||
|
# + -------+------------- incompatible v1.0.0
|
||||||
|
#
|
||||||
|
# The Go 1.17 module graph is the same except that the dependencies of
|
||||||
|
# requireincompatible are pruned out (because the module that requires
|
||||||
|
# it — lazy v0.1.0 — specifies 'go 1.17', and it is not otherwise relevant to
|
||||||
|
# the main module).
|
||||||
|
|
||||||
|
cp go.mod go.mod.orig
|
||||||
|
|
||||||
|
go mod graph
|
||||||
|
cp stdout graph-1.17.txt
|
||||||
|
stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$'
|
||||||
|
stdout '^example\.net/lazy@v0\.1\.0 example\.com/retract/incompatible@v1\.0\.0$'
|
||||||
|
! stdout 'example\.com/retract/incompatible@v2\.0\.0\+incompatible'
|
||||||
|
|
||||||
|
go mod graph -go=1.17
|
||||||
|
cmp stdout graph-1.17.txt
|
||||||
|
|
||||||
|
cmp go.mod go.mod.orig
|
||||||
|
|
||||||
|
|
||||||
|
# Setting -go=1.16 should report the graph as viewed by Go 1.16,
|
||||||
|
# but should not edit the go.mod file.
|
||||||
|
|
||||||
|
go mod graph -go=1.16
|
||||||
|
cp stdout graph-1.16.txt
|
||||||
|
stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$'
|
||||||
|
stdout '^example\.net/lazy@v0\.1\.0 example.com/retract/incompatible@v1\.0\.0$'
|
||||||
|
stdout '^example.net/requireincompatible@v0.1.0 example.com/retract/incompatible@v2\.0\.0\+incompatible$'
|
||||||
|
|
||||||
|
cmp go.mod go.mod.orig
|
||||||
|
|
||||||
|
|
||||||
|
# If we actually update the go.mod file to the requested go version,
|
||||||
|
# we should get the same selected versions, but the roots of the graph
|
||||||
|
# may be updated.
|
||||||
|
#
|
||||||
|
# TODO(#45551): The roots should not be updated.
|
||||||
|
|
||||||
|
go mod edit -go=1.16
|
||||||
|
go mod graph
|
||||||
|
! stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$'
|
||||||
|
stdout '^example\.net/lazy@v0.1.0 example.com/retract/incompatible@v1\.0\.0$'
|
||||||
|
stdout '^example.net/requireincompatible@v0.1.0 example.com/retract/incompatible@v2\.0\.0\+incompatible$'
|
||||||
|
# TODO(#45551): cmp stdout graph-1.16.txt
|
||||||
|
|
||||||
|
|
||||||
|
# Unsupported go versions should be rejected, since we don't know
|
||||||
|
# what versions they would report.
|
||||||
|
! go mod graph -go=1.99999999999
|
||||||
|
stderr '^invalid value "1\.99999999999" for flag -go: maximum supported Go version is '$goversion'\nusage: go mod graph \[-go=version\]\nRun ''go help mod graph'' for details.$'
|
||||||
|
|
||||||
|
|
||||||
|
-- go.mod --
|
||||||
|
// Module m indirectly imports a package from
|
||||||
|
// example.com/retract/incompatible. Its selected version of
|
||||||
|
// that module is lower under Go 1.17 semantics than under Go 1.16.
|
||||||
|
module example.com/m
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
replace (
|
||||||
|
example.net/lazy v0.1.0 => ./lazy
|
||||||
|
example.net/requireincompatible v0.1.0 => ./requireincompatible
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
example.com/retract/incompatible v1.0.0 // indirect
|
||||||
|
example.net/lazy v0.1.0
|
||||||
|
)
|
||||||
|
-- lazy/go.mod --
|
||||||
|
// Module lazy requires example.com/retract/incompatible v1.0.0.
|
||||||
|
//
|
||||||
|
// When viewed from the outside it also has a transitive dependency
|
||||||
|
// on v2.0.0+incompatible, but in lazy mode that transitive dependency
|
||||||
|
// is pruned out.
|
||||||
|
module example.net/lazy
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
exclude example.com/retract/incompatible v2.0.0+incompatible
|
||||||
|
|
||||||
|
require (
|
||||||
|
example.com/retract/incompatible v1.0.0
|
||||||
|
example.net/requireincompatible v0.1.0
|
||||||
|
)
|
||||||
|
-- requireincompatible/go.mod --
|
||||||
|
module example.net/requireincompatible
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
|
require example.com/retract/incompatible v2.0.0+incompatible
|
23
src/cmd/go/testdata/script/mod_list_test_cycle.txt
vendored
Normal file
23
src/cmd/go/testdata/script/mod_list_test_cycle.txt
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# https://golang.org/issue/45863: a typo in a test package leading to an
|
||||||
|
# import cycle should be diagnosed, instead of causing an infinite loop.
|
||||||
|
# The failure mode of this test prior to the fix was a timeout or OOM crash.
|
||||||
|
|
||||||
|
go list -e -test -deps ./datastore/sql
|
||||||
|
|
||||||
|
-- go.mod --
|
||||||
|
module golang.org/issue45863
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
-- datastore/datastore_health.go --
|
||||||
|
package datastore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/issue45863/datastore"
|
||||||
|
"golang.org/issue45863/datastore/sql"
|
||||||
|
)
|
||||||
|
-- datastore/sql/sql.go --
|
||||||
|
package sql
|
||||||
|
-- datastore/sql/sql_test.go --
|
||||||
|
package sql
|
||||||
|
|
||||||
|
import _ "golang.org/issue45863/datastore"
|
34
src/cmd/go/testdata/script/mod_tidy_replace_old.txt
vendored
Normal file
34
src/cmd/go/testdata/script/mod_tidy_replace_old.txt
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# Regression test for https://golang.org/issue/46659.
|
||||||
|
#
|
||||||
|
# If a 'replace' directive specifies an older-than-selected version of a module,
|
||||||
|
# 'go mod tidy' shouldn't try to add that version to the build list to resolve a
|
||||||
|
# missing package: it won't be selected, and would cause the module loader to
|
||||||
|
# loop indefinitely trying to resolve the package.
|
||||||
|
|
||||||
|
cp go.mod go.mod.orig
|
||||||
|
|
||||||
|
! go mod tidy
|
||||||
|
! stderr panic
|
||||||
|
stderr '^golang\.org/issue46659 imports\n\texample\.com/missingpkg/deprecated: package example\.com/missingpkg/deprecated provided by example\.com/missingpkg at latest version v1\.0\.0 but not at required version v1\.0\.1-beta$'
|
||||||
|
|
||||||
|
go mod tidy -e
|
||||||
|
|
||||||
|
cmp go.mod go.mod.orig
|
||||||
|
|
||||||
|
-- go.mod --
|
||||||
|
module golang.org/issue46659
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
replace example.com/missingpkg v1.0.1-alpha => example.com/missingpkg v1.0.0
|
||||||
|
|
||||||
|
require example.com/usemissingpre v1.0.0
|
||||||
|
|
||||||
|
require example.com/missingpkg v1.0.1-beta // indirect
|
||||||
|
-- m.go --
|
||||||
|
package m
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "example.com/missingpkg/deprecated"
|
||||||
|
_ "example.com/usemissingpre"
|
||||||
|
)
|
|
@ -5,6 +5,7 @@
|
||||||
package moddeps_test
|
package moddeps_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"internal/testenv"
|
"internal/testenv"
|
||||||
|
@ -68,7 +69,7 @@ func TestAllDependencies(t *testing.T) {
|
||||||
|
|
||||||
// There is no vendor directory, so the module must have no dependencies.
|
// There is no vendor directory, so the module must have no dependencies.
|
||||||
// Check that the list of active modules contains only the main module.
|
// Check that the list of active modules contains only the main module.
|
||||||
cmd := exec.Command(goBin, "list", "-mod=mod", "-m", "all")
|
cmd := exec.Command(goBin, "list", "-mod=readonly", "-m", "all")
|
||||||
cmd.Env = append(os.Environ(), "GO111MODULE=on")
|
cmd.Env = append(os.Environ(), "GO111MODULE=on")
|
||||||
cmd.Dir = m.Dir
|
cmd.Dir = m.Dir
|
||||||
cmd.Stderr = new(strings.Builder)
|
cmd.Stderr = new(strings.Builder)
|
||||||
|
@ -123,10 +124,38 @@ func TestAllDependencies(t *testing.T) {
|
||||||
t.Skip("skipping because a diff command with support for --recursive and --unified flags is unavailable")
|
t.Skip("skipping because a diff command with support for --recursive and --unified flags is unavailable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We're going to check the standard modules for tidiness, so we need a usable
|
||||||
|
// GOMODCACHE. If the default directory doesn't exist, use a temporary
|
||||||
|
// directory instead. (That can occur, for example, when running under
|
||||||
|
// run.bash with GO_TEST_SHORT=0: run.bash sets GOPATH=/nonexist-gopath, and
|
||||||
|
// GO_TEST_SHORT=0 causes it to run this portion of the test.)
|
||||||
|
var modcacheEnv []string
|
||||||
|
{
|
||||||
|
out, err := exec.Command(goBin, "env", "GOMODCACHE").Output()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s env GOMODCACHE: %v", goBin, err)
|
||||||
|
}
|
||||||
|
modcacheOk := false
|
||||||
|
if gomodcache := string(bytes.TrimSpace(out)); gomodcache != "" {
|
||||||
|
if _, err := os.Stat(gomodcache); err == nil {
|
||||||
|
modcacheOk = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !modcacheOk {
|
||||||
|
modcacheEnv = []string{
|
||||||
|
"GOMODCACHE=" + t.TempDir(),
|
||||||
|
"GOFLAGS=" + os.Getenv("GOFLAGS") + " -modcacherw", // Allow t.TempDir() to clean up subdirectories.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Build the bundle binary at the golang.org/x/tools
|
// Build the bundle binary at the golang.org/x/tools
|
||||||
// module version specified in GOROOT/src/cmd/go.mod.
|
// module version specified in GOROOT/src/cmd/go.mod.
|
||||||
bundleDir := t.TempDir()
|
bundleDir := t.TempDir()
|
||||||
r := runner{Dir: filepath.Join(runtime.GOROOT(), "src/cmd")}
|
r := runner{
|
||||||
|
Dir: filepath.Join(runtime.GOROOT(), "src/cmd"),
|
||||||
|
Env: append(os.Environ(), modcacheEnv...),
|
||||||
|
}
|
||||||
r.run(t, goBin, "build", "-mod=readonly", "-o", bundleDir, "golang.org/x/tools/cmd/bundle")
|
r.run(t, goBin, "build", "-mod=readonly", "-o", bundleDir, "golang.org/x/tools/cmd/bundle")
|
||||||
|
|
||||||
var gorootCopyDir string
|
var gorootCopyDir string
|
||||||
|
@ -160,7 +189,7 @@ func TestAllDependencies(t *testing.T) {
|
||||||
}
|
}
|
||||||
r := runner{
|
r := runner{
|
||||||
Dir: filepath.Join(gorootCopyDir, rel),
|
Dir: filepath.Join(gorootCopyDir, rel),
|
||||||
Env: append(os.Environ(),
|
Env: append(append(os.Environ(), modcacheEnv...),
|
||||||
// Set GOROOT.
|
// Set GOROOT.
|
||||||
"GOROOT="+gorootCopyDir,
|
"GOROOT="+gorootCopyDir,
|
||||||
// Explicitly override PWD and clear GOROOT_FINAL so that GOROOT=gorootCopyDir is definitely used.
|
// Explicitly override PWD and clear GOROOT_FINAL so that GOROOT=gorootCopyDir is definitely used.
|
||||||
|
|
|
@ -2841,7 +2841,6 @@ func TestTxStmtDeadlock(t *testing.T) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
tx, err := db.BeginTx(ctx, nil)
|
tx, err := db.BeginTx(ctx, nil)
|
||||||
cancel()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -2850,6 +2849,7 @@ func TestTxStmtDeadlock(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
cancel()
|
||||||
// Run number of stmt queries to reproduce deadlock from context cancel
|
// Run number of stmt queries to reproduce deadlock from context cancel
|
||||||
for i := 0; i < 1e3; i++ {
|
for i := 0; i < 1e3; i++ {
|
||||||
// Encounter any close related errors (e.g. ErrTxDone, stmt is closed)
|
// Encounter any close related errors (e.g. ErrTxDone, stmt is closed)
|
||||||
|
|
|
@ -1379,7 +1379,12 @@ func (p *parser) parseIndexOrSliceOrInstance(x ast.Expr) ast.Expr {
|
||||||
p.errorExpected(p.pos, "operand")
|
p.errorExpected(p.pos, "operand")
|
||||||
rbrack := p.pos
|
rbrack := p.pos
|
||||||
p.next()
|
p.next()
|
||||||
return &ast.BadExpr{From: x.Pos(), To: rbrack}
|
return &ast.IndexExpr{
|
||||||
|
X: x,
|
||||||
|
Lbrack: lbrack,
|
||||||
|
Index: &ast.BadExpr{From: rbrack, To: rbrack},
|
||||||
|
Rbrack: rbrack,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.exprLev++
|
p.exprLev++
|
||||||
|
|
||||||
|
|
|
@ -373,7 +373,7 @@ func (s *Scanner) scanIdentifier() string {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s.rdOffset += rdOffset
|
s.rdOffset += rdOffset
|
||||||
if b < utf8.RuneSelf {
|
if 0 < b && b < utf8.RuneSelf {
|
||||||
// Optimization: we've encountered an ASCII character that's not a letter
|
// Optimization: we've encountered an ASCII character that's not a letter
|
||||||
// or number. Avoid the call into s.next() and corresponding set up.
|
// or number. Avoid the call into s.next() and corresponding set up.
|
||||||
//
|
//
|
||||||
|
|
|
@ -813,6 +813,8 @@ var errors = []struct {
|
||||||
{"//\ufeff", token.COMMENT, 2, "//\ufeff", "illegal byte order mark"}, // only first BOM is ignored
|
{"//\ufeff", token.COMMENT, 2, "//\ufeff", "illegal byte order mark"}, // only first BOM is ignored
|
||||||
{"'\ufeff" + `'`, token.CHAR, 1, "'\ufeff" + `'`, "illegal byte order mark"}, // only first BOM is ignored
|
{"'\ufeff" + `'`, token.CHAR, 1, "'\ufeff" + `'`, "illegal byte order mark"}, // only first BOM is ignored
|
||||||
{`"` + "abc\ufeffdef" + `"`, token.STRING, 4, `"` + "abc\ufeffdef" + `"`, "illegal byte order mark"}, // only first BOM is ignored
|
{`"` + "abc\ufeffdef" + `"`, token.STRING, 4, `"` + "abc\ufeffdef" + `"`, "illegal byte order mark"}, // only first BOM is ignored
|
||||||
|
{"abc\x00def", token.IDENT, 3, "abc", "illegal character NUL"},
|
||||||
|
{"abc\x00", token.IDENT, 3, "abc", "illegal character NUL"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScanErrors(t *testing.T) {
|
func TestScanErrors(t *testing.T) {
|
||||||
|
|
|
@ -202,17 +202,20 @@ func asGoVersion(s string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, manual bool) {
|
func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, manual bool, imp Importer) {
|
||||||
if len(filenames) == 0 {
|
if len(filenames) == 0 {
|
||||||
t.Fatal("no source files")
|
t.Fatal("no source files")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.HasSuffix(filenames[0], ".go2") && !typeparams.Enabled {
|
||||||
|
t.Skip("type params are not enabled")
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(filenames[0], ".go1") && typeparams.Enabled {
|
||||||
|
t.Skip("type params are enabled")
|
||||||
|
}
|
||||||
|
|
||||||
mode := parser.AllErrors
|
mode := parser.AllErrors
|
||||||
if strings.HasSuffix(filenames[0], ".go2") {
|
if !strings.HasSuffix(filenames[0], ".go2") {
|
||||||
if !typeparams.Enabled {
|
|
||||||
t.Skip("type params are not enabled")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mode |= typeparams.DisallowParsing
|
mode |= typeparams.DisallowParsing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +253,10 @@ func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, man
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conf.Importer = importer.Default()
|
conf.Importer = imp
|
||||||
|
if imp == nil {
|
||||||
|
conf.Importer = importer.Default()
|
||||||
|
}
|
||||||
conf.Error = func(err error) {
|
conf.Error = func(err error) {
|
||||||
if *haltOnError {
|
if *haltOnError {
|
||||||
defer panic(err)
|
defer panic(err)
|
||||||
|
@ -339,7 +345,7 @@ func TestManual(t *testing.T) {
|
||||||
func TestLongConstants(t *testing.T) {
|
func TestLongConstants(t *testing.T) {
|
||||||
format := "package longconst\n\nconst _ = %s\nconst _ = %s // ERROR excessively long constant"
|
format := "package longconst\n\nconst _ = %s\nconst _ = %s // ERROR excessively long constant"
|
||||||
src := fmt.Sprintf(format, strings.Repeat("1", 9999), strings.Repeat("1", 10001))
|
src := fmt.Sprintf(format, strings.Repeat("1", 9999), strings.Repeat("1", 10001))
|
||||||
testFiles(t, nil, []string{"longconst.go"}, [][]byte{[]byte(src)}, false)
|
testFiles(t, nil, []string{"longconst.go"}, [][]byte{[]byte(src)}, false, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestIndexRepresentability tests that constant index operands must
|
// TestIndexRepresentability tests that constant index operands must
|
||||||
|
@ -347,7 +353,7 @@ func TestLongConstants(t *testing.T) {
|
||||||
// represent larger values.
|
// represent larger values.
|
||||||
func TestIndexRepresentability(t *testing.T) {
|
func TestIndexRepresentability(t *testing.T) {
|
||||||
const src = "package index\n\nvar s []byte\nvar _ = s[int64 /* ERROR \"int64\\(1\\) << 40 \\(.*\\) overflows int\" */ (1) << 40]"
|
const src = "package index\n\nvar s []byte\nvar _ = s[int64 /* ERROR \"int64\\(1\\) << 40 \\(.*\\) overflows int\" */ (1) << 40]"
|
||||||
testFiles(t, &StdSizes{4, 4}, []string{"index.go"}, [][]byte{[]byte(src)}, false)
|
testFiles(t, &StdSizes{4, 4}, []string{"index.go"}, [][]byte{[]byte(src)}, false, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue46453(t *testing.T) {
|
func TestIssue46453(t *testing.T) {
|
||||||
|
@ -355,7 +361,7 @@ func TestIssue46453(t *testing.T) {
|
||||||
t.Skip("type params are enabled")
|
t.Skip("type params are enabled")
|
||||||
}
|
}
|
||||||
const src = "package p\ntype _ comparable // ERROR \"undeclared name: comparable\""
|
const src = "package p\ntype _ comparable // ERROR \"undeclared name: comparable\""
|
||||||
testFiles(t, nil, []string{"issue46453.go"}, [][]byte{[]byte(src)}, false)
|
testFiles(t, nil, []string{"issue46453.go"}, [][]byte{[]byte(src)}, false, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCheck(t *testing.T) { DefPredeclaredTestFuncs(); testDirFiles(t, "testdata/check", false) }
|
func TestCheck(t *testing.T) { DefPredeclaredTestFuncs(); testDirFiles(t, "testdata/check", false) }
|
||||||
|
@ -415,5 +421,5 @@ func testPkg(t *testing.T, filenames []string, manual bool) {
|
||||||
}
|
}
|
||||||
srcs[i] = src
|
srcs[i] = src
|
||||||
}
|
}
|
||||||
testFiles(t, nil, filenames, srcs, manual)
|
testFiles(t, nil, filenames, srcs, manual, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ func (check *Checker) qualifier(pkg *Package) string {
|
||||||
if check.pkgPathMap == nil {
|
if check.pkgPathMap == nil {
|
||||||
check.pkgPathMap = make(map[string]map[string]bool)
|
check.pkgPathMap = make(map[string]map[string]bool)
|
||||||
check.seenPkgMap = make(map[*Package]bool)
|
check.seenPkgMap = make(map[*Package]bool)
|
||||||
check.markImports(pkg)
|
check.markImports(check.pkg)
|
||||||
}
|
}
|
||||||
// If the same package name was used by multiple packages, display the full path.
|
// If the same package name was used by multiple packages, display the full path.
|
||||||
if len(check.pkgPathMap[pkg.name]) > 1 {
|
if len(check.pkgPathMap[pkg.name]) > 1 {
|
||||||
|
|
|
@ -577,42 +577,64 @@ func TestIssue44515(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue43124(t *testing.T) {
|
func TestIssue43124(t *testing.T) {
|
||||||
// TODO(rFindley) enhance the testdata tests to be able to express this type
|
// TODO(rFindley) move this to testdata by enhancing support for importing.
|
||||||
// of setup.
|
|
||||||
|
|
||||||
// All involved packages have the same name (template). Error messages should
|
// All involved packages have the same name (template). Error messages should
|
||||||
// disambiguate between text/template and html/template by printing the full
|
// disambiguate between text/template and html/template by printing the full
|
||||||
// path.
|
// path.
|
||||||
const (
|
const (
|
||||||
asrc = `package a; import "text/template"; func F(template.Template) {}; func G(int) {}`
|
asrc = `package a; import "text/template"; func F(template.Template) {}; func G(int) {}`
|
||||||
bsrc = `package b; import ("a"; "html/template"); func _() { a.F(template.Template{}) }`
|
bsrc = `
|
||||||
csrc = `package c; import ("a"; "html/template"); func _() { a.G(template.Template{}) }`
|
package b
|
||||||
|
|
||||||
|
import (
|
||||||
|
"a"
|
||||||
|
"html/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// Packages should be fully qualified when there is ambiguity within the
|
||||||
|
// error string itself.
|
||||||
|
a.F(template /* ERROR cannot use.*html/template.* as .*text/template */ .Template{})
|
||||||
|
}
|
||||||
|
`
|
||||||
|
csrc = `
|
||||||
|
package c
|
||||||
|
|
||||||
|
import (
|
||||||
|
"a"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Issue #46905: make sure template is not the first package qualified.
|
||||||
|
var _ fmt.Stringer = 1 // ERROR cannot use 1.*as fmt\.Stringer
|
||||||
|
|
||||||
|
// Packages should be fully qualified when there is ambiguity in reachable
|
||||||
|
// packages. In this case both a (and for that matter html/template) import
|
||||||
|
// text/template.
|
||||||
|
func _() { a.G(template /* ERROR cannot use .*html/template.*Template */ .Template{}) }
|
||||||
|
`
|
||||||
|
|
||||||
|
tsrc = `
|
||||||
|
package template
|
||||||
|
|
||||||
|
import "text/template"
|
||||||
|
|
||||||
|
type T int
|
||||||
|
|
||||||
|
// Verify that the current package name also causes disambiguation.
|
||||||
|
var _ T = template /* ERROR cannot use.*text/template.* as T value */.Template{}
|
||||||
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
a, err := pkgFor("a", asrc, nil)
|
a, err := pkgFor("a", asrc, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("package a failed to typecheck: %v", err)
|
t.Fatalf("package a failed to typecheck: %v", err)
|
||||||
}
|
}
|
||||||
conf := Config{Importer: importHelper{pkg: a, fallback: importer.Default()}}
|
imp := importHelper{pkg: a, fallback: importer.Default()}
|
||||||
|
|
||||||
// Packages should be fully qualified when there is ambiguity within the
|
testFiles(t, nil, []string{"b.go"}, [][]byte{[]byte(bsrc)}, false, imp)
|
||||||
// error string itself.
|
testFiles(t, nil, []string{"c.go"}, [][]byte{[]byte(csrc)}, false, imp)
|
||||||
bast := mustParse(t, bsrc)
|
testFiles(t, nil, []string{"t.go"}, [][]byte{[]byte(tsrc)}, false, imp)
|
||||||
_, err = conf.Check(bast.Name.Name, fset, []*ast.File{bast}, nil)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("package b had no errors")
|
|
||||||
}
|
|
||||||
if !strings.Contains(err.Error(), "text/template") || !strings.Contains(err.Error(), "html/template") {
|
|
||||||
t.Errorf("type checking error for b does not disambiguate package template: %q", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...and also when there is any ambiguity in reachable packages.
|
|
||||||
cast := mustParse(t, csrc)
|
|
||||||
_, err = conf.Check(cast.Name.Name, fset, []*ast.File{cast}, nil)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("package c had no errors")
|
|
||||||
}
|
|
||||||
if !strings.Contains(err.Error(), "html/template") {
|
|
||||||
t.Errorf("type checking error for c does not disambiguate package template: %q", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
4
src/go/types/testdata/check/issues.src
vendored
4
src/go/types/testdata/check/issues.src
vendored
|
@ -332,7 +332,7 @@ func issue28281g() (... /* ERROR can only use ... with final parameter */ TT)
|
||||||
func issue26234a(f *syn.File) {
|
func issue26234a(f *syn.File) {
|
||||||
// The error message below should refer to the actual package name (syntax)
|
// The error message below should refer to the actual package name (syntax)
|
||||||
// not the local package name (syn).
|
// not the local package name (syn).
|
||||||
f.foo /* ERROR f.foo undefined \(type \*syntax.File has no field or method foo\) */
|
f.foo /* ERROR f\.foo undefined \(type \*syntax\.File has no field or method foo\) */
|
||||||
}
|
}
|
||||||
|
|
||||||
type T struct {
|
type T struct {
|
||||||
|
@ -361,7 +361,7 @@ func issue35895() {
|
||||||
|
|
||||||
// Because both t1 and t2 have the same global package name (template),
|
// Because both t1 and t2 have the same global package name (template),
|
||||||
// qualify packages with full path name in this case.
|
// qualify packages with full path name in this case.
|
||||||
var _ t1.Template = t2 /* ERROR cannot use .* \(value of type "html/template".Template\) as "text/template".Template */ .Template{}
|
var _ t1.Template = t2 /* ERROR cannot use .* \(value of type .html/template.\.Template\) as .text/template.\.Template */ .Template{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func issue42989(s uint) {
|
func issue42989(s uint) {
|
||||||
|
|
2
src/go/types/testdata/examples/functions.go2
vendored
2
src/go/types/testdata/examples/functions.go2
vendored
|
@ -210,5 +210,5 @@ func _() {
|
||||||
func h[] /* ERROR empty type parameter list */ ()
|
func h[] /* ERROR empty type parameter list */ ()
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
h[] /* ERROR operand */ ()
|
h /* ERROR cannot index */ [] /* ERROR operand */ ()
|
||||||
}
|
}
|
||||||
|
|
11
src/go/types/testdata/fixedbugs/issue46403.src
vendored
Normal file
11
src/go/types/testdata/fixedbugs/issue46403.src
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package issue46403
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// a should be used, despite the parser error below.
|
||||||
|
var a []int
|
||||||
|
var _ = a[] // ERROR expected operand
|
||||||
|
}
|
8
src/go/types/testdata/fixedbugs/issue46404.go1
vendored
Normal file
8
src/go/types/testdata/fixedbugs/issue46404.go1
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package issue46404
|
||||||
|
|
||||||
|
// Check that we don't type check t[_] as an instantiation.
|
||||||
|
type t [t /* ERROR not a type */ [_]]_ // ERROR cannot use
|
|
@ -262,8 +262,12 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case *ast.IndexExpr:
|
case *ast.IndexExpr:
|
||||||
exprs := typeparams.UnpackExpr(e.Index)
|
if typeparams.Enabled {
|
||||||
return check.instantiatedType(e.X, exprs, def)
|
exprs := typeparams.UnpackExpr(e.Index)
|
||||||
|
return check.instantiatedType(e.X, exprs, def)
|
||||||
|
}
|
||||||
|
check.errorf(e0, _NotAType, "%s is not a type", e0)
|
||||||
|
check.use(e.X)
|
||||||
|
|
||||||
case *ast.ParenExpr:
|
case *ast.ParenExpr:
|
||||||
// Generic types must be instantiated before they can be used in any form.
|
// Generic types must be instantiated before they can be used in any form.
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
//
|
//
|
||||||
// (This is not necessarily the set of experiments the compiler itself
|
// (This is not necessarily the set of experiments the compiler itself
|
||||||
// was built with.)
|
// was built with.)
|
||||||
var Experiment goexperiment.Flags = parseExperiments()
|
var Experiment goexperiment.Flags = parseExperiments(GOARCH)
|
||||||
|
|
||||||
var regabiSupported = GOARCH == "amd64" || GOARCH == "arm64"
|
var regabiSupported = GOARCH == "amd64" || GOARCH == "arm64"
|
||||||
var regabiDeveloping = false
|
var regabiDeveloping = false
|
||||||
|
@ -41,7 +41,7 @@ var experimentBaseline = goexperiment.Flags{
|
||||||
// Note: must agree with runtime.framepointer_enabled.
|
// Note: must agree with runtime.framepointer_enabled.
|
||||||
var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
|
var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
|
||||||
|
|
||||||
func parseExperiments() goexperiment.Flags {
|
func parseExperiments(goarch string) goexperiment.Flags {
|
||||||
// Start with the statically enabled set of experiments.
|
// Start with the statically enabled set of experiments.
|
||||||
flags := experimentBaseline
|
flags := experimentBaseline
|
||||||
|
|
||||||
|
@ -96,11 +96,11 @@ func parseExperiments() goexperiment.Flags {
|
||||||
}
|
}
|
||||||
|
|
||||||
// regabiwrappers is always enabled on amd64.
|
// regabiwrappers is always enabled on amd64.
|
||||||
if GOARCH == "amd64" {
|
if goarch == "amd64" {
|
||||||
flags.RegabiWrappers = true
|
flags.RegabiWrappers = true
|
||||||
}
|
}
|
||||||
// regabi is only supported on amd64 and arm64.
|
// regabi is only supported on amd64 and arm64.
|
||||||
if GOARCH != "amd64" && GOARCH != "arm64" {
|
if goarch != "amd64" && goarch != "arm64" {
|
||||||
flags.RegabiWrappers = false
|
flags.RegabiWrappers = false
|
||||||
flags.RegabiReflect = false
|
flags.RegabiReflect = false
|
||||||
flags.RegabiArgs = false
|
flags.RegabiArgs = false
|
||||||
|
@ -161,3 +161,10 @@ func EnabledExperiments() []string {
|
||||||
func AllExperiments() []string {
|
func AllExperiments() []string {
|
||||||
return expList(&Experiment, nil, true)
|
return expList(&Experiment, nil, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateExperiments updates the Experiment global based on a new GOARCH value.
|
||||||
|
// This is only required for cmd/go, which can change GOARCH after
|
||||||
|
// program startup due to use of "go env -w".
|
||||||
|
func UpdateExperiments(goarch string) {
|
||||||
|
Experiment = parseExperiments(goarch)
|
||||||
|
}
|
||||||
|
|
|
@ -155,40 +155,27 @@ func slowDialTCP(ctx context.Context, network string, laddr, raddr *TCPAddr) (*T
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func dialClosedPort(t *testing.T) (actual, expected time.Duration) {
|
func dialClosedPort(t *testing.T) (dialLatency time.Duration) {
|
||||||
// Estimate the expected time for this platform.
|
// On most platforms, dialing a closed port should be nearly instantaneous —
|
||||||
// On Windows, dialing a closed port takes roughly 1 second,
|
// less than a few hundred milliseconds. However, on some platforms it may be
|
||||||
// but other platforms should be instantaneous.
|
// much slower: on Windows and OpenBSD, it has been observed to take up to a
|
||||||
if runtime.GOOS == "windows" {
|
// few seconds.
|
||||||
expected = 1500 * time.Millisecond
|
|
||||||
} else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
|
|
||||||
expected = 150 * time.Millisecond
|
|
||||||
} else {
|
|
||||||
expected = 95 * time.Millisecond
|
|
||||||
}
|
|
||||||
|
|
||||||
l, err := Listen("tcp", "127.0.0.1:0")
|
l, err := Listen("tcp", "127.0.0.1:0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Logf("dialClosedPort: Listen failed: %v", err)
|
t.Fatalf("dialClosedPort: Listen failed: %v", err)
|
||||||
return 999 * time.Hour, expected
|
|
||||||
}
|
}
|
||||||
addr := l.Addr().String()
|
addr := l.Addr().String()
|
||||||
l.Close()
|
l.Close()
|
||||||
// On OpenBSD, interference from TestTCPSelfConnect is mysteriously
|
|
||||||
// causing the first attempt to hang for a few seconds, so we throw
|
startTime := time.Now()
|
||||||
// away the first result and keep the second.
|
c, err := Dial("tcp", addr)
|
||||||
for i := 1; ; i++ {
|
if err == nil {
|
||||||
startTime := time.Now()
|
c.Close()
|
||||||
c, err := Dial("tcp", addr)
|
|
||||||
if err == nil {
|
|
||||||
c.Close()
|
|
||||||
}
|
|
||||||
elapsed := time.Now().Sub(startTime)
|
|
||||||
if i == 2 {
|
|
||||||
t.Logf("dialClosedPort: measured delay %v", elapsed)
|
|
||||||
return elapsed, expected
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
elapsed := time.Now().Sub(startTime)
|
||||||
|
t.Logf("dialClosedPort: measured delay %v", elapsed)
|
||||||
|
return elapsed
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDialParallel(t *testing.T) {
|
func TestDialParallel(t *testing.T) {
|
||||||
|
@ -198,10 +185,7 @@ func TestDialParallel(t *testing.T) {
|
||||||
t.Skip("both IPv4 and IPv6 are required")
|
t.Skip("both IPv4 and IPv6 are required")
|
||||||
}
|
}
|
||||||
|
|
||||||
closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
|
closedPortDelay := dialClosedPort(t)
|
||||||
if closedPortDelay > expectClosedPortDelay {
|
|
||||||
t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
|
|
||||||
}
|
|
||||||
|
|
||||||
const instant time.Duration = 0
|
const instant time.Duration = 0
|
||||||
const fallbackDelay = 200 * time.Millisecond
|
const fallbackDelay = 200 * time.Millisecond
|
||||||
|
@ -675,10 +659,7 @@ func TestDialerDualStack(t *testing.T) {
|
||||||
t.Skip("both IPv4 and IPv6 are required")
|
t.Skip("both IPv4 and IPv6 are required")
|
||||||
}
|
}
|
||||||
|
|
||||||
closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
|
closedPortDelay := dialClosedPort(t)
|
||||||
if closedPortDelay > expectClosedPortDelay {
|
|
||||||
t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
|
|
||||||
}
|
|
||||||
|
|
||||||
origTestHookLookupIP := testHookLookupIP
|
origTestHookLookupIP := testHookLookupIP
|
||||||
defer func() { testHookLookupIP = origTestHookLookupIP }()
|
defer func() { testHookLookupIP = origTestHookLookupIP }()
|
||||||
|
|
|
@ -299,7 +299,7 @@ func lookupPTR(name string) (ptr []string, err error) {
|
||||||
ptr = make([]string, 0, 10)
|
ptr = make([]string, 0, 10)
|
||||||
rx := regexp.MustCompile(`(?m)^Pinging\s+([a-zA-Z0-9.\-]+)\s+\[.*$`)
|
rx := regexp.MustCompile(`(?m)^Pinging\s+([a-zA-Z0-9.\-]+)\s+\[.*$`)
|
||||||
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
|
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
|
||||||
ptr = append(ptr, ans[1]+".")
|
ptr = append(ptr, absDomainName([]byte(ans[1])))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,6 @@ func TestFifoEOF(t *testing.T) {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "android":
|
case "android":
|
||||||
t.Skip("skipping on Android; mkfifo syscall not available")
|
t.Skip("skipping on Android; mkfifo syscall not available")
|
||||||
case "openbsd":
|
|
||||||
// On OpenBSD 6.2 this test just hangs for some reason.
|
|
||||||
t.Skip("skipping on OpenBSD; issue 25877")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
|
|
|
@ -1377,10 +1377,16 @@ func valueInterface(v Value, safe bool) interface{} {
|
||||||
return packEface(v)
|
return packEface(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceData returns the interface v's value as a uintptr pair.
|
// InterfaceData returns a pair of unspecified uintptr values.
|
||||||
// It panics if v's Kind is not Interface.
|
// It panics if v's Kind is not Interface.
|
||||||
|
//
|
||||||
|
// In earlier versions of Go, this function returned the interface's
|
||||||
|
// value as a uintptr pair. As of Go 1.4, the implementation of
|
||||||
|
// interface values precludes any defined use of InterfaceData.
|
||||||
|
//
|
||||||
|
// Deprecated: The memory representation of interface values is not
|
||||||
|
// compatible with InterfaceData.
|
||||||
func (v Value) InterfaceData() [2]uintptr {
|
func (v Value) InterfaceData() [2]uintptr {
|
||||||
// TODO: deprecate this
|
|
||||||
v.mustBe(Interface)
|
v.mustBe(Interface)
|
||||||
// We treat this as a read operation, so we allow
|
// We treat this as a read operation, so we allow
|
||||||
// it even for unexported data, because the caller
|
// it even for unexported data, because the caller
|
||||||
|
|
|
@ -65,7 +65,7 @@ TEXT ·Xaddint64(SB), NOSPLIT, $0-20
|
||||||
|
|
||||||
// bool ·Cas64(uint64 *val, uint64 old, uint64 new)
|
// bool ·Cas64(uint64 *val, uint64 old, uint64 new)
|
||||||
// Atomically:
|
// Atomically:
|
||||||
// if(*val == *old){
|
// if(*val == old){
|
||||||
// *val = new;
|
// *val = new;
|
||||||
// return 1;
|
// return 1;
|
||||||
// } else {
|
// } else {
|
||||||
|
|
|
@ -751,8 +751,11 @@ type ParseError struct {
|
||||||
|
|
||||||
// These are borrowed from unicode/utf8 and strconv and replicate behavior in
|
// These are borrowed from unicode/utf8 and strconv and replicate behavior in
|
||||||
// that package, since we can't take a dependency on either.
|
// that package, since we can't take a dependency on either.
|
||||||
const runeSelf = 0x80
|
const (
|
||||||
const lowerhex = "0123456789abcdef"
|
lowerhex = "0123456789abcdef"
|
||||||
|
runeSelf = 0x80
|
||||||
|
runeError = '\uFFFD'
|
||||||
|
)
|
||||||
|
|
||||||
func quote(s string) string {
|
func quote(s string) string {
|
||||||
buf := make([]byte, 1, len(s)+2) // slice will be at least len(s) + quotes
|
buf := make([]byte, 1, len(s)+2) // slice will be at least len(s) + quotes
|
||||||
|
@ -765,7 +768,16 @@ func quote(s string) string {
|
||||||
// reproduce strconv.Quote's behavior with full fidelity but
|
// reproduce strconv.Quote's behavior with full fidelity but
|
||||||
// given how rarely we expect to hit these edge cases, speed and
|
// given how rarely we expect to hit these edge cases, speed and
|
||||||
// conciseness are better.
|
// conciseness are better.
|
||||||
for j := 0; j < len(string(c)) && j < len(s); j++ {
|
var width int
|
||||||
|
if c == runeError {
|
||||||
|
width = 1
|
||||||
|
if i+2 < len(s) && s[i:i+3] == string(runeError) {
|
||||||
|
width = 3
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
width = len(string(c))
|
||||||
|
}
|
||||||
|
for j := 0; j < width; j++ {
|
||||||
buf = append(buf, `\x`...)
|
buf = append(buf, `\x`...)
|
||||||
buf = append(buf, lowerhex[s[i+j]>>4])
|
buf = append(buf, lowerhex[s[i+j]>>4])
|
||||||
buf = append(buf, lowerhex[s[i+j]&0xF])
|
buf = append(buf, lowerhex[s[i+j]&0xF])
|
||||||
|
|
|
@ -917,6 +917,11 @@ var parseDurationErrorTests = []struct {
|
||||||
{".s", `".s"`},
|
{".s", `".s"`},
|
||||||
{"+.s", `"+.s"`},
|
{"+.s", `"+.s"`},
|
||||||
{"1d", `"1d"`},
|
{"1d", `"1d"`},
|
||||||
|
{"\x85\x85", `"\x85\x85"`},
|
||||||
|
{"\xffff", `"\xffff"`},
|
||||||
|
{"hello \xffff world", `"hello \xffff world"`},
|
||||||
|
{"\uFFFD", `"\xef\xbf\xbd"`}, // utf8.RuneError
|
||||||
|
{"\uFFFD hello \uFFFD world", `"\xef\xbf\xbd hello \xef\xbf\xbd world"`}, // utf8.RuneError
|
||||||
// overflow
|
// overflow
|
||||||
{"9223372036854775810ns", `"9223372036854775810ns"`},
|
{"9223372036854775810ns", `"9223372036854775810ns"`},
|
||||||
{"9223372036854775808ns", `"9223372036854775808ns"`},
|
{"9223372036854775808ns", `"9223372036854775808ns"`},
|
||||||
|
|
11
test/fixedbugs/issue46907.go
Normal file
11
test/fixedbugs/issue46907.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// compile
|
||||||
|
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package p
|
||||||
|
|
||||||
|
func f(b []byte) []byte {
|
||||||
|
return (*[32]byte)(b[:32])[:]
|
||||||
|
}
|
Loading…
Reference in a new issue