Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package govulncheck for openSUSE:Factory checked in at 2026-08-18 16:37:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/govulncheck (Old) and /work/SRC/openSUSE:Factory/.govulncheck.new.1258 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "govulncheck" Tue Aug 18 16:37:11 2026 rev:19 rq:1371640 version:1.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/govulncheck/govulncheck.changes 2026-07-10 17:41:22.145315505 +0200 +++ /work/SRC/openSUSE:Factory/.govulncheck.new.1258/govulncheck.changes 2026-08-18 16:37:56.908077069 +0200 @@ -1,0 +2,6 @@ +Thu Aug 13 18:01:04 UTC 2026 - Jeff Kowalczyk <[email protected]> + +- Update to version 1.7.0: + * go.mod: update golang.org/x dependencies + +------------------------------------------------------------------- Old: ---- govulncheck-1.6.0.tar.gz New: ---- govulncheck-1.7.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ govulncheck.spec ++++++ --- /var/tmp/diff_new_pack.1dckiz/_old 2026-08-18 16:37:57.755107379 +0200 +++ /var/tmp/diff_new_pack.1dckiz/_new 2026-08-18 16:37:57.757107450 +0200 @@ -17,7 +17,7 @@ Name: govulncheck -Version: 1.6.0 +Version: 1.7.0 Release: 0 Summary: CLI tool to report known CVE vulnerabilities in Go source code and binaries License: BSD-3-Clause ++++++ _service ++++++ --- /var/tmp/diff_new_pack.1dckiz/_old 2026-08-18 16:37:57.826109919 +0200 +++ /var/tmp/diff_new_pack.1dckiz/_new 2026-08-18 16:37:57.834110206 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/golang/vuln.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v1.6.0</param> + <param name="revision">v1.7.0</param> <param name="versionformat">@PARENT_TAG@+git@TAG_OFFSET@.%h</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*?)(\+git0\.?.*?)?$</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.1dckiz/_old 2026-08-18 16:37:57.873111601 +0200 +++ /var/tmp/diff_new_pack.1dckiz/_new 2026-08-18 16:37:57.877111744 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/golang/vuln.git</param> - <param name="changesrevision">19b0bb6a272792b9afa8a6983c3e9b9a1816947f</param></service></servicedata> + <param name="changesrevision">617f44b718537dccdea1915395650e0529e3b72e</param></service></servicedata> (No newline at EOF) ++++++ govulncheck-1.6.0.tar.gz -> govulncheck-1.7.0.tar.gz ++++++ /work/SRC/openSUSE:Factory/govulncheck/govulncheck-1.6.0.tar.gz /work/SRC/openSUSE:Factory/.govulncheck.new.1258/govulncheck-1.7.0.tar.gz differ: char 12, line 1 ++++++ vendor.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/go/ast/inspector/cursor.go new/vendor/golang.org/x/tools/go/ast/inspector/cursor.go --- old/vendor/golang.org/x/tools/go/ast/inspector/cursor.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/go/ast/inspector/cursor.go 2026-08-13 20:01:04.000000000 +0200 @@ -10,6 +10,7 @@ "go/token" "iter" "reflect" + "strings" "golang.org/x/tools/go/ast/edge" ) @@ -110,6 +111,46 @@ return reflect.TypeOf(c.Node()).String() } +// GoString returns a string describing the cursor's path from the +// root, if any. +func (c Cursor) GoString() string { + if !c.Valid() { + return "(invalid)" + } + if c.index < 0 { + return "(root)" + } + // e.g "File.Decls[1].(*ast.GenDecl).Specs[0].(*ast.TypeSpec)" + // + // In hindsight even the File node should have reported a + // virtual ParentEdge of (Root_Files, i) where i is the index + // among the files passed to NewInspector. Then the path would + // read "(root).Files[i]", etc; but we missed the boat. + var buf strings.Builder + buf.WriteString("File") + var visit func(Cursor) + visit = func(c Cursor) { + ek, idx := c.ParentEdge() + if ek == edge.Invalid { + return // File + } + visit(c.Parent()) + fmt.Fprintf(&buf, ".%s", ek.FieldName()) + if idx >= 0 { + fmt.Fprintf(&buf, "[%d]", idx) + } + ftype := ek.FieldType() + if idx >= 0 { + ftype = ftype.Elem() // []T -> T + } + if ftype.Kind() == reflect.Interface { + fmt.Fprintf(&buf, ".(%T)", c.Node()) + } + } + visit(c) + return buf.String() +} + // indices return the [start, end) half-open interval of event indices. func (c Cursor) indices() (int32, int32) { if c.index < 0 { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/go/loader/loader.go new/vendor/golang.org/x/tools/go/loader/loader.go --- old/vendor/golang.org/x/tools/go/loader/loader.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/go/loader/loader.go 2026-08-13 20:01:04.000000000 +0200 @@ -738,7 +738,9 @@ // Preprocess CgoFiles and parse the outputs (sequentially). if which == 'g' && bp.CgoFiles != nil { + ioLimit <- true cgofiles, err := cgo.ProcessFiles(bp, conf.fset(), conf.DisplayPath, conf.ParserMode) + <-ioLimit if err != nil { errs = append(errs, err) } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/go/packages/visit.go new/vendor/golang.org/x/tools/go/packages/visit.go --- old/vendor/golang.org/x/tools/go/packages/visit.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/go/packages/visit.go 2026-08-13 20:01:04.000000000 +0200 @@ -5,11 +5,11 @@ package packages import ( - "cmp" "fmt" "iter" "os" - "slices" + + "golang.org/x/tools/internal/moremaps" ) // Visit visits all the packages in the import graph whose roots are @@ -40,7 +40,7 @@ seen[pkg] = true if pre == nil || pre(pkg) { - for _, imp := range sorted(pkg.Imports) { // for determinism + for _, imp := range moremaps.Sorted(pkg.Imports) { // for determinism visit(imp) } } @@ -88,7 +88,7 @@ visit = func(pkg *Package) bool { if !seen[pkg] { seen[pkg] = true - for _, imp := range sorted(pkg.Imports) { // for determinism + for _, imp := range moremaps.Sorted(pkg.Imports) { // for determinism if !visit(imp) { return false } @@ -106,28 +106,3 @@ } } } - -// -- copied from golang.org.x/tools/gopls/internal/util/moremaps -- - -// sorted returns an iterator over the entries of m in key order. -func sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] { - // TODO(adonovan): use maps.Sorted if proposal #68598 is accepted. - return func(yield func(K, V) bool) { - keys := keySlice(m) - slices.Sort(keys) - for _, k := range keys { - if !yield(k, m[k]) { - break - } - } - } -} - -// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)). -func keySlice[M ~map[K]V, K comparable, V any](m M) []K { - r := make([]K, 0, len(m)) - for k := range m { - r = append(r, k) - } - return r -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/go/ssa/builder.go new/vendor/golang.org/x/tools/go/ssa/builder.go --- old/vendor/golang.org/x/tools/go/ssa/builder.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/go/ssa/builder.go 2026-08-13 20:01:04.000000000 +0200 @@ -85,6 +85,7 @@ "slices" "golang.org/x/tools/internal/typeparams" + "golang.org/x/tools/internal/typesinternal" "golang.org/x/tools/internal/versions" ) @@ -124,7 +125,7 @@ // The ssa:deferstack intrinsic returns the current function's defer stack. vDeferStack = &Builtin{ name: "ssa:deferstack", - sig: types.NewSignatureType(nil, nil, nil, nil, types.NewTuple(anonVar(tDeferStack)), false), + sig: types.NewSignatureType(nil, nil, nil, nil, typesinternal.TupleOf(tDeferStack), false), } ) @@ -1719,7 +1720,7 @@ for _, st := range states { if st.Dir == types.RecvOnly { chtyp := typeparams.CoreType(fn.typ(st.Chan.Type())).(*types.Chan) - vars = append(vars, anonVar(chtyp.Elem())) + vars = append(vars, newVar("", chtyp.Elem())) } } sel.setType(types.NewTuple(vars...)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/go/ssa/methods.go new/vendor/golang.org/x/tools/go/ssa/methods.go --- old/vendor/golang.org/x/tools/go/ssa/methods.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/go/ssa/methods.go 2026-08-13 20:01:04.000000000 +0200 @@ -167,10 +167,18 @@ // eliminates the need to eagerly compute all the element // types during SSA building. var runtimeTypes []types.Type - add := func(t types.Type) { runtimeTypes = append(runtimeTypes, t) } var set typeutil.Map // for de-duping identical types for t := range prog.makeInterfaceTypes { - typesinternal.ForEachElement(&set, &prog.MethodSets, t, add) + typesinternal.ForEachElement(prog.MethodSets.MethodSet, t, func(t types.Type, access bool) bool { + if !access { + return false // inaccessible to reflection + } + seen, _ := set.Set(t, true).(bool) + if !seen { + runtimeTypes = append(runtimeTypes, t) + } + return seen + }) } return runtimeTypes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/go/ssa/util.go new/vendor/golang.org/x/tools/go/ssa/util.go --- old/vendor/golang.org/x/tools/go/ssa/util.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/go/ssa/util.go 2026-08-13 20:01:04.000000000 +0200 @@ -181,19 +181,13 @@ return types.NewParam(token.NoPos, nil, name, typ) } -// anonVar creates an anonymous 'var' for use in a types.Tuple. -func anonVar(typ types.Type) *types.Var { - return newVar("", typ) -} - -var lenResults = types.NewTuple(anonVar(tInt)) +var lenResults = typesinternal.TupleOf(tInt) // makeLen returns the len builtin specialized to type func(T)int. func makeLen(T types.Type) *Builtin { - lenParams := types.NewTuple(anonVar(T)) return &Builtin{ name: "len", - sig: types.NewSignatureType(nil, nil, nil, lenParams, lenResults, false), + sig: types.NewSignatureType(nil, nil, nil, typesinternal.TupleOf(T), lenResults, false), } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/go/ssa/wrappers.go new/vendor/golang.org/x/tools/go/ssa/wrappers.go --- old/vendor/golang.org/x/tools/go/ssa/wrappers.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/go/ssa/wrappers.go 2026-08-13 20:01:04.000000000 +0200 @@ -26,6 +26,7 @@ "go/types" "golang.org/x/tools/internal/typeparams" + "golang.org/x/tools/internal/typesinternal" ) // -- wrappers ----------------------------------------------------------- @@ -118,10 +119,12 @@ // For simple indirection wrappers, perform an informative nil-check: // "value method (T).f called using nil *T pointer" if len(indices) == 1 && !isPointer(recvType(fn.object)) { + params := typesinternal.TupleOf(fn.method.recv, tString, tString) + results := typesinternal.TupleOf(fn.method.recv) var c Call c.Call.Value = &Builtin{ name: "ssa:wrapnilchk", - sig: types.NewSignatureType(nil, nil, nil, types.NewTuple(anonVar(fn.method.recv), anonVar(tString), anonVar(tString)), types.NewTuple(anonVar(fn.method.recv)), false), + sig: types.NewSignatureType(nil, nil, nil, params, results, false), } c.Call.Args = []Value{ v, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/go/types/typeutil/callee.go new/vendor/golang.org/x/tools/go/types/typeutil/callee.go --- old/vendor/golang.org/x/tools/go/types/typeutil/callee.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/go/types/typeutil/callee.go 2026-08-13 20:01:04.000000000 +0200 @@ -7,7 +7,8 @@ import ( "go/ast" "go/types" - _ "unsafe" // for linkname + + "golang.org/x/tools/internal/typesinternal" ) // Callee returns the named target of a function call, if any: @@ -19,14 +20,7 @@ // Note: for calls of instantiated functions and methods, Callee returns // the corresponding generic function or method on the generic type. func Callee(info *types.Info, call *ast.CallExpr) types.Object { - obj := info.Uses[usedIdent(info, call.Fun)] - if obj == nil { - return nil - } - if _, ok := obj.(*types.TypeName); ok { - return nil - } - return obj + return typesinternal.Callee(info, call) } // StaticCallee returns the target (function or method) of a static function @@ -35,52 +29,5 @@ // Note: for calls of instantiated functions and methods, StaticCallee returns // the corresponding generic function or method on the generic type. func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { - obj := info.Uses[usedIdent(info, call.Fun)] - fn, _ := obj.(*types.Func) - if fn == nil || interfaceMethod(fn) { - return nil - } - return fn -} - -// usedIdent is the implementation of [internal/typesinternal.UsedIdent]. -// It returns the identifier associated with e. -// See typesinternal.UsedIdent for a fuller description. -// This function should live in typesinternal, but cannot because it would -// create an import cycle. -// -//go:linkname usedIdent golang.org/x/tools/go/types/typeutil.usedIdent -func usedIdent(info *types.Info, e ast.Expr) *ast.Ident { - if info.Types == nil || info.Uses == nil { - panic("one of info.Types or info.Uses is nil; both must be populated") - } - // Look through type instantiation if necessary. - switch d := ast.Unparen(e).(type) { - case *ast.IndexExpr: - if info.Types[d.Index].IsType() { - e = d.X - } - case *ast.IndexListExpr: - e = d.X - } - - switch e := ast.Unparen(e).(type) { - // info.Uses always has the object we want, even for selector expressions. - // We don't need info.Selections. - // See go/types/recording.go:recordSelection. - case *ast.Ident: - return e - case *ast.SelectorExpr: - return e.Sel - } - return nil -} - -// interfaceMethod reports whether its argument is a method of an interface. -// This function should live in typesinternal, but cannot because it would create an import cycle. -// -//go:linkname interfaceMethod golang.org/x/tools/go/types/typeutil.interfaceMethod -func interfaceMethod(f *types.Func) bool { - recv := f.Signature().Recv() - return recv != nil && types.IsInterface(recv.Type()) + return typesinternal.StaticCallee(info, call) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/internal/moremaps/maps.go new/vendor/golang.org/x/tools/internal/moremaps/maps.go --- old/vendor/golang.org/x/tools/internal/moremaps/maps.go 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/golang.org/x/tools/internal/moremaps/maps.go 2026-08-13 20:01:04.000000000 +0200 @@ -0,0 +1,116 @@ +// Copyright 2023 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 moremaps contains more functions for working with maps. +package moremaps + +import ( + "cmp" + "iter" + "maps" + "slices" +) + +// Arbitrary returns an arbitrary (key, value) entry from the map and ok is true, if +// the map is not empty. Otherwise, it returns zero values for K and V, and false. +func Arbitrary[K comparable, V any](m map[K]V) (_ K, _ V, ok bool) { + for k, v := range m { + return k, v, true + } + return +} + +// Group returns a new non-nil map containing the elements of s grouped by the +// keys returned from the key func. +func Group[K comparable, V any](s []V, key func(V) K) map[K][]V { + m := make(map[K][]V) + for _, v := range s { + k := key(v) + m[k] = append(m[k], v) + } + return m +} + +// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)). +func KeySlice[M ~map[K]V, K comparable, V any](m M) []K { + r := make([]K, 0, len(m)) + for k := range m { + r = append(r, k) + } + return r +} + +// ValueSlice returns the values of the map M, like slices.Collect(maps.Values(m)). +func ValueSlice[M ~map[K]V, K comparable, V any](m M) []V { + r := make([]V, 0, len(m)) + for _, v := range m { + r = append(r, v) + } + return r +} + +// SameKeys reports whether x and y have equal sets of keys. +func SameKeys[K comparable, V1, V2 any](x map[K]V1, y map[K]V2) bool { + ignoreValues := func(V1, V2) bool { return true } + return maps.EqualFunc(x, y, ignoreValues) +} + +// Sorted returns an iterator over the entries of m in key order. +func Sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] { + // TODO(adonovan): use maps.Sorted if proposal #68598 is accepted. + return func(yield func(K, V) bool) { + keys := KeySlice(m) + slices.Sort(keys) + for _, k := range keys { + if !yield(k, m[k]) { + break + } + } + } +} + +// SortedFunc returns an iterator over the entries of m in the key order determined by cmp. +func SortedFunc[M ~map[K]V, K comparable, V any](m M, cmp func(x, y K) int) iter.Seq2[K, V] { + // TODO(adonovan): use maps.SortedFunc if proposal #68598 is accepted. + return func(yield func(K, V) bool) { + keys := KeySlice(m) + slices.SortFunc(keys, cmp) + for _, k := range keys { + if !yield(k, m[k]) { + break + } + } + } +} + +// Delete is like delete(m, k) but reports whether deletion occurred. +func Delete[M ~map[K]V, K comparable, V any](m M, k K) bool { + pre := len(m) + delete(m, k) + return pre != len(m) +} + +// Entry is a key-value pair obtained from a map. +type Entry[K comparable, V any] struct { + Key K + Value V +} + +// Entries returns a new unordered array of the entries of a map. +func Entries[M ~map[K]V, K comparable, V any](m M) []Entry[K, V] { + entries := make([]Entry[K, V], 0, len(m)) + for k, v := range m { + entries = append(entries, Entry[K, V]{k, v}) + } + return entries +} + +// FromEntries returns a new map into which the entries have been inserted in order. +func FromEntries[K comparable, V any](entries []Entry[K, V]) map[K]V { + m := make(map[K]V, len(entries)) + for _, e := range entries { + m[e.Key] = e.Value + } + return m +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go new/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go --- old/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go 2026-08-13 20:01:04.000000000 +0200 @@ -0,0 +1,128 @@ +// Copyright 2026 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 typesinternal + +import ( + "go/ast" + "go/token" + "go/types" + + "golang.org/x/tools/go/ast/edge" + "golang.org/x/tools/go/ast/inspector" +) + +// IsAssignedOrAddressTaken reports whether the expression cur denotes a +// variable and appears in a context that assigns it or that takes its address, +// potentially leading to indirect assignment. +// +// These examples cause IsAssignedOrAddressTaken on the identifier for x to +// return true: +// +// x = 1 +// x++ +// x[i] = 1 (assume x is an array) +// x.a[i] = 1 (assume x.a is a non-pointer struct field) +// use(&x) +// +// whereas these cause it to return false: +// +// y = x +// f(x) +// use(x.a[i]) +// use(*x) +// +// The expression may itself be a compound, for example: +// +// use(&(*ptr)) => IsAssignedOrAddressTaken("*ptr") = true +// x.a[i] = 1 => IsAssignedOrAddressTaken("x.a") = true +// _ = x.a[i] => IsAssignedOrAddressTaken("x.a") = false +// +// A variable's declaration is not considered to be an assignment: +// +// var x int => IsAssignedOrAddressTaken(x) = false +// x := 1 => IsAssignedOrAddressTaken(x) = false +// +// TODO(adonovan): revisit the surprising behavior for declarations. +func IsAssignedOrAddressTaken(info *types.Info, cur inspector.Cursor) bool { + // Unfortunately we can't simply use info.Types[e].Assignable() + // as it is always true for a variable even when that variable is + // used only as an r-value. So we must inspect enclosing syntax. +outer: + // Ascend to outermost aggregate of which + // original cur is a part: + // x -> (x) | x.f | x[i] | x[i:j] + for cur = range cur.Enclosing() { + switch cur.ParentEdgeKind() { + case edge.ParenExpr_X: + // If x is an lvalue, then (x) is an lvalue. + case edge.SelectorExpr_X: + // If x is an lvalue, then x.f is an lvalue iff + // the selection does not traverse a pointer. + sel := cur.Parent().Node().(*ast.SelectorExpr) + if seln, ok := info.Selections[sel]; ok { + // Note: there is a bug in Indirect() where it spuriously returns true + // when both the selection receiver and parameter are pointers. However, + // it's okay in this case because there is no address taken when a + // pointer receiver method is called on a pointer type. + if seln.Indirect() { + return false + } + if seln.Kind() == types.MethodVal { + sig := seln.Obj().Type().(*types.Signature) + if is[*types.Pointer](sig.Recv().Type().Underlying()) { + t := seln.Recv() + // The receiver may be an embedded field, so we need + // to get the inner-most type (right before the method + // call in seln.Index()) + for _, idx := range seln.Index()[:len(seln.Index())-1] { + t = t.Underlying().(*types.Struct).Field(idx).Type() + } + if !is[*types.Pointer](t.Underlying()) { + return true // takes address of receiver + } + } + return false + } + } + case edge.IndexExpr_X, edge.SliceExpr_X: + // If x[i] or x[i:j] is an lvalue, + // then x is an lvalue iff x is an array. + if !is[*types.Array](info.TypeOf(cur.Node().(ast.Expr)).Underlying()) { + return false + } + default: + break outer + } + } + switch cur.ParentEdgeKind() { + case edge.AssignStmt_Lhs: + assign := cur.Parent().Node().(*ast.AssignStmt) + if assign.Tok != token.DEFINE { + return true // x = j or x += j + } + id := cur.Node().(*ast.Ident) + // Re-assigned identifiers are recorded in the Uses map. + if _, ok := info.Uses[id]; ok { + return true // reassignment of x (x, y := 1, 2) + } + case edge.RangeStmt_Key, edge.RangeStmt_Value: + rng := cur.Parent().Node().(*ast.RangeStmt) + if rng.Tok == token.ASSIGN { + return true // "for k, v = range x" is like an AssignStmt to k, v + } + case edge.IncDecStmt_X: + return true // x++, x-- + case edge.UnaryExpr_X: + if cur.Parent().Node().(*ast.UnaryExpr).Op == token.AND { + return true // &x + } + } + return false +} + +func is[T any](x any) bool { + _, ok := x.(T) + return ok +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go new/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go --- old/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go 2026-08-13 20:01:04.000000000 +0200 @@ -8,7 +8,6 @@ "fmt" "go/ast" "go/types" - _ "unsafe" // for go:linkname hack ) // CallKind describes the function position of an [*ast.CallExpr]. @@ -72,11 +71,15 @@ if tv.IsBuiltin() { return CallBuiltin } - obj := info.Uses[UsedIdent(info, call.Fun)] + id := UsedIdent(info, call.Fun) + if id == nil { + return CallDynamic + } + obj := info.Uses[id] // Classify the call by the type of the object, if any. switch obj := obj.(type) { case *types.Func: - if interfaceMethod(obj) { + if isInterfaceMethod(obj) { return CallInterface } return CallStatic @@ -127,11 +130,69 @@ // Note: if e is an instantiated function or method, UsedIdent returns // the corresponding generic function or method on the generic type. func UsedIdent(info *types.Info, e ast.Expr) *ast.Ident { - return usedIdent(info, e) + if info.Types == nil || info.Uses == nil { + panic("one of info.Types or info.Uses is nil; both must be populated") + } + // Look through type instantiation if necessary. + switch d := ast.Unparen(e).(type) { + case *ast.IndexExpr: + if info.Types[d.Index].IsType() { + e = d.X + } + case *ast.IndexListExpr: + e = d.X + } + + switch e := ast.Unparen(e).(type) { + // info.Uses always has the object we want, even for selector expressions. + // We don't need info.Selections. + // See go/types/recording.go:recordSelection. + case *ast.Ident: + return e + case *ast.SelectorExpr: + return e.Sel + } + return nil +} + +// See [golang.org/x/tools/go/types/typeutil.Callee]. +func Callee(info *types.Info, call *ast.CallExpr) types.Object { + id := UsedIdent(info, call.Fun) + if id == nil { + return nil + } + obj := info.Uses[id] + if obj == nil { + return nil + } + if _, ok := obj.(*types.TypeName); ok { + return nil + } + if fn, ok := obj.(*types.Func); ok { + return fn.Origin() + } + return obj } -//go:linkname usedIdent golang.org/x/tools/go/types/typeutil.usedIdent -func usedIdent(info *types.Info, e ast.Expr) *ast.Ident +// See [golang.org/x/tools/go/types/typeutil.StaticCallee]. +func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { + id := UsedIdent(info, call.Fun) + if id == nil { + return nil + } + obj := info.Uses[id] + if obj == nil { + return nil + } + fn, _ := obj.(*types.Func) + if fn == nil || isInterfaceMethod(fn) { + return nil + } + return fn.Origin() +} -//go:linkname interfaceMethod golang.org/x/tools/go/types/typeutil.interfaceMethod -func interfaceMethod(f *types.Func) bool +// isInterfaceMethod reports whether its argument is a method of an interface. +func isInterfaceMethod(f *types.Func) bool { + recv := f.Signature().Recv() + return recv != nil && types.IsInterface(recv.Type()) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/internal/typesinternal/element.go new/vendor/golang.org/x/tools/internal/typesinternal/element.go --- old/vendor/golang.org/x/tools/internal/typesinternal/element.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/internal/typesinternal/element.go 2026-08-13 20:01:04.000000000 +0200 @@ -7,8 +7,6 @@ import ( "fmt" "go/types" - - "golang.org/x/tools/go/types/typeutil" ) // ForEachElement calls f for type T and each type reachable from its @@ -16,25 +14,24 @@ // type constructors; in addition, for each named type N, the type *N // is added to the result as it may have additional methods. // -// The caller must provide an initially empty set used to de-duplicate -// identical types, potentially across multiple calls to ForEachElement. -// (Its final value holds all the elements seen, matching the arguments -// passed to f.) +// The access argument passed to f indicates whether the type is +// inaccessible to reflection (for example, intermediate tuple types +// or underlying types of named types). // -// TODO(adonovan): share/harmonize with go/callgraph/rta. -func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T types.Type, f func(types.Type)) { - var visit func(T types.Type, skip bool) - visit = func(T types.Type, skip bool) { - if !skip { - if seen, _ := rtypes.Set(T, true).(bool); seen { - return // de-dup - } - - f(T) // notify caller of new element type +// The result of f indicates whether the caller has seen this type +// already, so we can prune the traversal. +// +// methodSetOf abstracts (*typeutil.MethodSetCache).MethodSet, +// avoiding an import cycle. +func ForEachElement(methodSetOf func(types.Type) *types.MethodSet, T types.Type, f func(T types.Type, access bool) bool) { + var visit func(T types.Type, access bool) + visit = func(T types.Type, access bool) { + if f(T, access) { + return // duplicate; prune descent } // Recursion over signatures of each method. - tmset := msets.MethodSet(T) + tmset := methodSetOf(T) for method := range tmset.Methods() { sig := method.Type().(*types.Signature) if sig.TypeParams() != nil { @@ -65,13 +62,13 @@ // // TODO(adonovan): document whether or not it is // safe to skip non-exported methods (as RTA does). - visit(sig.Params(), true) // skip the Tuple - visit(sig.Results(), true) // skip the Tuple + visit(sig.Params(), false) // the Tuple is inaccessible + visit(sig.Results(), false) // the Tuple is inaccessible } switch T := T.(type) { case *types.Alias: - visit(types.Unalias(T), skip) // emulates the pre-Alias behavior + visit(types.Unalias(T), access) // emulates the pre-Alias behavior case *types.Basic: // nop @@ -80,49 +77,49 @@ // nop---handled by recursion over method set. case *types.Pointer: - visit(T.Elem(), false) + visit(T.Elem(), true) case *types.Slice: - visit(T.Elem(), false) + visit(T.Elem(), true) case *types.Chan: - visit(T.Elem(), false) + visit(T.Elem(), true) case *types.Map: - visit(T.Key(), false) - visit(T.Elem(), false) + visit(T.Key(), true) + visit(T.Elem(), true) case *types.Signature: if T.Recv() != nil { panic(fmt.Sprintf("Signature %s has Recv %s", T, T.Recv())) } - visit(T.Params(), true) // skip the Tuple - visit(T.Results(), true) // skip the Tuple + visit(T.Params(), false) // the Tuple is inaccessible + visit(T.Results(), false) // the Tuple is inaccessible case *types.Named: // A pointer-to-named type can be derived from a named // type via reflection. It may have methods too. - visit(types.NewPointer(T), false) + visit(types.NewPointer(T), true) // Consider 'type T struct{S}' where S has methods. // Reflection provides no way to get from T to struct{S}, // only to S, so the method set of struct{S} is unwanted, - // so set 'skip' flag during recursion. - visit(T.Underlying(), true) // skip the unnamed type + // so mark it inaccessible during recursion. + visit(T.Underlying(), false) // skip the unnamed type case *types.Array: - visit(T.Elem(), false) + visit(T.Elem(), true) case *types.Struct: for i, n := 0, T.NumFields(); i < n; i++ { // TODO(adonovan): document whether or not // it is safe to skip non-exported fields. - visit(T.Field(i).Type(), false) + visit(T.Field(i).Type(), true) } case *types.Tuple: for i, n := 0, T.Len(); i < n; i++ { - visit(T.At(i).Type(), false) + visit(T.At(i).Type(), true) } case *types.TypeParam, *types.Union: @@ -133,5 +130,5 @@ panic(fmt.Sprintf("ForEachElement called on unexpected type %T", T)) } } - visit(T, false) + visit(T, true) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/internal/typesinternal/toonew.go new/vendor/golang.org/x/tools/internal/typesinternal/toonew.go --- old/vendor/golang.org/x/tools/internal/typesinternal/toonew.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/internal/typesinternal/toonew.go 2026-08-13 20:01:04.000000000 +0200 @@ -13,20 +13,30 @@ // TooNewStdSymbols computes the set of package-level symbols // exported by pkg that are not available at the specified version. -// The result maps each symbol to its minimum version. // // The pkg is allowed to contain type errors. -func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]string { - disallowed := make(map[types.Object]string) +func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]stdlib.Symbol { + disallowed := make(map[types.Object]stdlib.Symbol) + + // Some symbols are accessible before their release but + // only with specific build tags unknown to us here. + // Avoid false positives in such cases. + if pkg.Path() == "testing/synctest" && versions.AtLeast(version, "go1.24") { + // requires go1.24 && goexperiment.synctest || go1.25 + return disallowed + } + if (pkg.Path() == "encoding/json/v2" || pkg.Path() == "encoding/json/jsontext") && versions.AtLeast(version, "go1.25") { + // requires go1.25 && goexperiment.jsonv2 || go1.27 + return disallowed + } // Pass 1: package-level symbols. symbols := stdlib.PackageSymbols[pkg.Path()] for _, sym := range symbols { - symver := sym.Version.String() - if versions.Before(version, symver) { + if versions.Before(version, sym.Version.String()) { switch sym.Kind { case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type: - disallowed[pkg.Scope().Lookup(sym.Name)] = symver + disallowed[pkg.Scope().Lookup(sym.Name)] = sym } } } @@ -60,28 +70,36 @@ // spuriously cause the analyzer to report a reference to a // too-new symbol even though this expression compiles just // fine (with the fake implementation) using go1.21. + var noSym stdlib.Symbol + depth := make(map[types.Object]int) for _, sym := range symbols { - symVersion := sym.Version.String() - if !versions.Before(version, symVersion) { + if !versions.Before(version, sym.Version.String()) { continue // allowed } var obj types.Object + var indices []int switch sym.Kind { case stdlib.Field: typename, name := sym.SplitField() - if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == "" { - obj, _, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name) + if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == noSym { + obj, indices, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name) } case stdlib.Method: ptr, recvname, name := sym.SplitMethod() - if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == "" { - obj, _, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name) + if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == noSym { + obj, indices, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name) } } if obj != nil { - disallowed[obj] = symVersion + // In the presence of embedding, two or more "pkg.T.name" + // strings may map to the same types.Object. + // Prefer the Object with the shorter index path. + if min, ok := depth[obj]; !ok || len(indices) < min { + depth[obj] = len(indices) + disallowed[obj] = sym + } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/tools/internal/typesinternal/types.go new/vendor/golang.org/x/tools/internal/typesinternal/types.go --- old/vendor/golang.org/x/tools/internal/typesinternal/types.go 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/golang.org/x/tools/internal/typesinternal/types.go 2026-08-13 20:01:04.000000000 +0200 @@ -270,3 +270,11 @@ } } } + +func TupleOf(elems ...types.Type) *types.Tuple { + params := make([]*types.Var, len(elems)) + for i, elem := range elems { + params[i] = types.NewParam(token.NoPos, nil, "", elem) + } + return types.NewTuple(params...) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt --- old/vendor/modules.txt 2026-07-09 19:23:02.000000000 +0200 +++ new/vendor/modules.txt 2026-08-13 20:01:04.000000000 +0200 @@ -12,7 +12,7 @@ # github.com/google/renameio v0.1.0 ## explicit github.com/google/renameio -# golang.org/x/mod v0.38.0 +# golang.org/x/mod v0.39.0 ## explicit; go 1.25.0 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile @@ -24,7 +24,7 @@ # golang.org/x/sys v0.47.0 ## explicit; go 1.25.0 golang.org/x/sys/windows -# golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 +# golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5 ## explicit; go 1.25.0 golang.org/x/telemetry golang.org/x/telemetry/counter @@ -35,7 +35,7 @@ golang.org/x/telemetry/internal/mmap golang.org/x/telemetry/internal/telemetry golang.org/x/telemetry/internal/upload -# golang.org/x/tools v0.48.0 +# golang.org/x/tools v0.49.0 ## explicit; go 1.25.0 golang.org/x/tools/go/ast/astutil golang.org/x/tools/go/ast/edge @@ -61,6 +61,7 @@ golang.org/x/tools/internal/event/label golang.org/x/tools/internal/gcimporter golang.org/x/tools/internal/gocommand +golang.org/x/tools/internal/moremaps golang.org/x/tools/internal/packagesinternal golang.org/x/tools/internal/pkgbits golang.org/x/tools/internal/proxydir
