Skip to content

Commit

Permalink
all: merge master (1b39a8b) into gopls-release-branch.0.15
Browse files Browse the repository at this point in the history
Also add back the local replace directive.

For golang/go#64973

Conflicts:

- gopls/go.sum

Merge List:

+ 2024-02-13 1b39a8b internal/testenv: always Cleanup to appease go vet
+ 2024-02-13 afd8428 gopls/internal/test/integration: slightly more ergonomic FolderSettings
+ 2024-02-12 c5643e9 gopls/internal/server: fix two bugs related to dynamic configuration
+ 2024-02-12 50b4f1b gopls/internal/golang: close open file
+ 2024-02-09 f0ef3c6 gopls: update x/telemetry dependency to fix crash
+ 2024-02-09 8cf0a8e gopls: record that v0.15 will be the last to support go1.18
+ 2024-02-09 730dc3c gopls/internal/settings: add a hidden option to disable zero config
+ 2024-02-09 95f04f4 gopls/internal/golang: add resolve support for inline refactorings
+ 2024-02-09 9619683 gopls/internal/cache: treat local replaces as workspace modules
+ 2024-02-09 a5af84e gopls/internal/cache: check views on any on-disk change to go.mod files
+ 2024-02-09 a7407fa gopls: update telemetry
+ 2024-02-08 314368d go/analysis/passes/deepequalerrors: audit for types.Alias safety
+ 2024-02-08 f4fa7a7 go.mod: update golang.org/x dependencies
+ 2024-02-07 5fcc627 go/analysis/passes/nilness: handle type assertions too
+ 2024-02-07 e3f1180 gopls/internal/cache: fix crash in analysis
+ 2024-02-07 76ef6b6 internal/jsonrpc2: export WireError type
+ 2024-02-07 acf07b3 gopls/internal/utils/immutable: remove unused Map.Keys
+ 2024-02-07 c11269c gopls/semantic: elide zero-length tokens
+ 2024-02-07 7f80389 go/analysis/passes/stringintconv: audit for types.Alias safety
+ 2024-02-07 76795ef gopls/doc: audit for types.Alias safety
+ 2024-02-06 ab67961 internal/imports: update stdlib index for Go 1.22.0
+ 2024-02-06 d64ed6a internal/refactor/inline: audit for types.Alias safety
+ 2024-02-06 0d87589 go/types/typeutil: audit for types.Alias safety

Change-Id: Icee623a693061afd9f7eb3779427b3b294bf271f
  • Loading branch information
findleyr committed Feb 13, 2024
2 parents 9f736d6 + 1b39a8b commit c2dba44
Show file tree
Hide file tree
Showing 45 changed files with 793 additions and 121 deletions.
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ go 1.18

require (
github.com/yuin/goldmark v1.4.13
golang.org/x/mod v0.14.0
golang.org/x/net v0.20.0
golang.org/x/mod v0.15.0
golang.org/x/net v0.21.0
)

require golang.org/x/sync v0.6.0

require (
golang.org/x/sys v0.16.0 // indirect
golang.org/x/telemetry v0.0.0-20240201224847-0a1d30dda509
golang.org/x/sys v0.17.0 // indirect
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808
)
14 changes: 8 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240201224847-0a1d30dda509 h1:Nr7eTQpQZ/ytesxDJpQgaf0t4sdLnnDtAbmtViTrSUo=
golang.org/x/telemetry v0.0.0-20240201224847-0a1d30dda509/go.mod h1:ZthVHHkOi8rlMEsfFr3Ie42Ym1NonbFNNRKW3ci0UrU=
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808 h1:+Kc94D8UVEVxJnLXp/+FMfqQARZtWHfVrcRtcG8aT3g=
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ=
26 changes: 23 additions & 3 deletions go/analysis/analysistest/analysistest.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"os"
"path/filepath"
"regexp"
"runtime"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -128,6 +129,19 @@ type Testing interface {
func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns ...string) []*Result {
r := Run(t, dir, a, patterns...)

// If the immediate caller of RunWithSuggestedFixes is in
// x/tools, we apply stricter checks as required by gopls.
inTools := false
{
var pcs [1]uintptr
n := runtime.Callers(1, pcs[:])
frames := runtime.CallersFrames(pcs[:n])
fr, _ := frames.Next()
if fr.Func != nil && strings.HasPrefix(fr.Func.Name(), "golang.org/x/tools/") {
inTools = true
}
}

// Process each result (package) separately, matching up the suggested
// fixes into a diff, which we will compare to the .golden file. We have
// to do this per-result in case a file appears in two packages, such as in
Expand All @@ -145,8 +159,14 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns

// Validate edits, prepare the fileEdits map and read the file contents.
for _, diag := range act.Diagnostics {
for _, sf := range diag.SuggestedFixes {
for _, edit := range sf.TextEdits {
for _, fix := range diag.SuggestedFixes {

// Assert that lazy fixes have a Category (#65578, #65087).
if inTools && len(fix.TextEdits) == 0 && diag.Category == "" {
t.Errorf("missing Diagnostic.Category for SuggestedFix without TextEdits (gopls requires the category for the name of the fix command")
}

for _, edit := range fix.TextEdits {
start, end := edit.Pos, edit.End
if !end.IsValid() {
end = start
Expand Down Expand Up @@ -175,7 +195,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
if _, ok := fileEdits[file]; !ok {
fileEdits[file] = make(map[string][]diff.Edit)
}
fileEdits[file][sf.Message] = append(fileEdits[file][sf.Message], diff.Edit{
fileEdits[file][fix.Message] = append(fileEdits[file][fix.Message], diff.Edit{
Start: file.Offset(start),
End: file.Offset(end),
New: string(edit.NewText),
Expand Down
4 changes: 3 additions & 1 deletion go/analysis/passes/deepequalerrors/deepequalerrors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
"golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/go/types/typeutil"
"golang.org/x/tools/internal/aliases"
)

const Doc = `check for calls of reflect.DeepEqual on error values
Expand Down Expand Up @@ -101,7 +102,8 @@ func containsError(typ types.Type) bool {
return true
}
}
case *types.Named:
case *types.Named,
*aliases.Alias:
return check(t.Underlying())

// We list the remaining valid type kinds for completeness.
Expand Down
56 changes: 56 additions & 0 deletions go/analysis/passes/nilness/nilness.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,42 @@ func runFunc(pass *analysis.Pass, fn *ssa.Function) {
}
}

// In code of the form:
//
// if ptr, ok := x.(*T); ok { ... } else { fsucc }
//
// the fsucc block learns that ptr == nil,
// since that's its zero value.
if If, ok := b.Instrs[len(b.Instrs)-1].(*ssa.If); ok {
// Handle "if ok" and "if !ok" variants.
cond, fsucc := If.Cond, b.Succs[1]
if unop, ok := cond.(*ssa.UnOp); ok && unop.Op == token.NOT {
cond, fsucc = unop.X, b.Succs[0]
}

// Match pattern:
// t0 = typeassert (pointerlike)
// t1 = extract t0 #0 // ptr
// t2 = extract t0 #1 // ok
// if t2 goto tsucc, fsucc
if extract1, ok := cond.(*ssa.Extract); ok && extract1.Index == 1 {
if assert, ok := extract1.Tuple.(*ssa.TypeAssert); ok &&
isNillable(assert.AssertedType) {
for _, pinstr := range *assert.Referrers() {
if extract0, ok := pinstr.(*ssa.Extract); ok &&
extract0.Index == 0 &&
extract0.Tuple == extract1.Tuple {
for _, d := range b.Dominees() {
if len(d.Preds) == 1 && d == fsucc {
visit(d, append(stack, fact{extract0, isnil}))
}
}
}
}
}
}
}

for _, d := range b.Dominees() {
visit(d, stack)
}
Expand Down Expand Up @@ -360,3 +396,23 @@ func (ff facts) negate() facts {
}
return nn
}

func is[T any](x any) bool {
_, ok := x.(T)
return ok
}

func isNillable(t types.Type) bool {
switch t := typeparams.CoreType(t).(type) {
case *types.Pointer,
*types.Map,
*types.Signature,
*types.Chan,
*types.Interface,
*types.Slice:
return true
case *types.Basic:
return t == types.Typ[types.UnsafePointer]
}
return false
}
26 changes: 26 additions & 0 deletions go/analysis/passes/nilness/testdata/src/a/a.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,29 @@ func f14() {
print(x)
}
}

func f15(x any) {
ptr, ok := x.(*int)
if ok {
return
}
println(*ptr) // want "nil dereference in load"
}

func f16(x any) {
ptr, ok := x.(*int)
if !ok {
println(*ptr) // want "nil dereference in load"
return
}
println(*ptr)
}

func f18(x any) {
ptr, ok := x.(*int)
if ok {
println(ptr)
// falls through
}
println(*ptr)
}
8 changes: 4 additions & 4 deletions go/analysis/passes/stringintconv/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
"golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/internal/aliases"
"golang.org/x/tools/internal/typeparams"
)

Expand Down Expand Up @@ -194,16 +195,15 @@ func run(pass *analysis.Pass) (interface{}, error) {

func structuralTypes(t types.Type) ([]types.Type, error) {
var structuralTypes []types.Type
switch t := t.(type) {
case *types.TypeParam:
terms, err := typeparams.StructuralTerms(t)
if tp, ok := aliases.Unalias(t).(*types.TypeParam); ok {
terms, err := typeparams.StructuralTerms(tp)
if err != nil {
return nil, err
}
for _, term := range terms {
structuralTypes = append(structuralTypes, term.Type())
}
default:
} else {
structuralTypes = append(structuralTypes, t)
}
return structuralTypes, nil
Expand Down
7 changes: 7 additions & 0 deletions go/types/typeutil/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"go/types"
"reflect"

"golang.org/x/tools/internal/aliases"
"golang.org/x/tools/internal/typeparams"
)

Expand Down Expand Up @@ -259,6 +260,9 @@ func (h Hasher) hashFor(t types.Type) uint32 {
case *types.Basic:
return uint32(t.Kind())

case *aliases.Alias:
return h.Hash(t.Underlying())

case *types.Array:
return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem())

Expand Down Expand Up @@ -457,6 +461,9 @@ func (h Hasher) shallowHash(t types.Type) uint32 {
// elements (mostly Slice, Pointer, Basic, Named),
// so there's no need to optimize anything else.
switch t := t.(type) {
case *aliases.Alias:
return h.shallowHash(t.Underlying())

case *types.Signature:
var hash uint32 = 604171
if t.Variadic() {
Expand Down
29 changes: 29 additions & 0 deletions go/types/typeutil/map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,15 @@ var Issue56048 = Issue56048_I.m
type Issue56048_Ib interface{ m() chan []*interface { Issue56048_Ib } }
var Issue56048b = Issue56048_Ib.m
// Non-generic alias
type NonAlias int
type Alias1 = NonAlias
type Alias2 = NonAlias
// Generic alias (requires go1.23)
// type SetOfInt = map[int]bool
// type Set[T comparable] = map[K]bool
// type SetOfInt2 = Set[int]
`

fset := token.NewFileSet()
Expand Down Expand Up @@ -307,6 +316,16 @@ var Issue56048b = Issue56048_Ib.m
Quux = scope.Lookup("Quux").Type()
Issue56048 = scope.Lookup("Issue56048").Type()
Issue56048b = scope.Lookup("Issue56048b").Type()

// In go1.23 these will be *types.Alias; for now they are all int.
NonAlias = scope.Lookup("NonAlias").Type()
Alias1 = scope.Lookup("Alias1").Type()
Alias2 = scope.Lookup("Alias2").Type()

// Requires go1.23.
// SetOfInt = scope.Lookup("SetOfInt").Type()
// Set = scope.Lookup("Set").Type().(*types.Alias)
// SetOfInt2 = scope.Lookup("SetOfInt2").Type()
)

tmap := new(typeutil.Map)
Expand Down Expand Up @@ -379,6 +398,16 @@ var Issue56048b = Issue56048_Ib.m

{Issue56048, "Issue56048", true}, // (not actually about generics)
{Issue56048b, "Issue56048b", true}, // (not actually about generics)

// All three types are identical.
{NonAlias, "NonAlias", true},
{Alias1, "Alias1", false},
{Alias2, "Alias2", false},

// Generic aliases: requires go1.23.
// {SetOfInt, "SetOfInt", true},
// {Set, "Set", false},
// {SetOfInt2, "SetOfInt2", false},
}

for _, step := range steps {
Expand Down
6 changes: 4 additions & 2 deletions go/types/typeutil/methodsetcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ package typeutil
import (
"go/types"
"sync"

"golang.org/x/tools/internal/aliases"
)

// A MethodSetCache records the method set of each type T for which
Expand All @@ -32,12 +34,12 @@ func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
cache.mu.Lock()
defer cache.mu.Unlock()

switch T := T.(type) {
switch T := aliases.Unalias(T).(type) {
case *types.Named:
return cache.lookupNamed(T).value

case *types.Pointer:
if N, ok := T.Elem().(*types.Named); ok {
if N, ok := aliases.Unalias(T.Elem()).(*types.Named); ok {
return cache.lookupNamed(N).pointer
}
}
Expand Down
1 change: 1 addition & 0 deletions gopls/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ version of gopls.
| Go 1.12 | [gopls@v0.7.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.7.5) |
| Go 1.15 | [gopls@v0.9.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.9.5) |
| Go 1.17 | [gopls@v0.11.0](https://github.com/golang/tools/releases/tag/gopls%2Fv0.11.0) |
| Go 1.18 | [gopls@v0.14.2](https://github.com/golang/tools/releases/tag/gopls%2Fv0.14.2) |

Our extended support is enforced via [continuous integration with older Go
versions](doc/contributing.md#ci). This legacy Go CI may not block releases:
Expand Down
4 changes: 2 additions & 2 deletions gopls/doc/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func loadOptions(category reflect.Value, optsType types.Object, pkg *packages.Pa
name := lowerFirst(typesField.Name())

var enumKeys settings.EnumKeys
if m, ok := typesField.Type().(*types.Map); ok {
if m, ok := typesField.Type().Underlying().(*types.Map); ok {
e, ok := enums[m.Key()]
if ok {
typ = strings.Replace(typ, m.Key().String(), m.Key().Underlying().String(), 1)
Expand Down Expand Up @@ -313,7 +313,7 @@ func collectEnumKeys(name string, m *types.Map, reflectField reflect.Value, enum
}
// We can get default values for enum -> bool maps.
var isEnumBoolMap bool
if basic, ok := m.Elem().(*types.Basic); ok && basic.Kind() == types.Bool {
if basic, ok := m.Elem().Underlying().(*types.Basic); ok && basic.Kind() == types.Bool {
isEnumBoolMap = true
}
for _, v := range enumValues {
Expand Down
8 changes: 5 additions & 3 deletions gopls/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ require (
github.com/google/go-cmp v0.6.0
github.com/jba/printsrc v0.2.2
github.com/jba/templatecheck v0.6.0
golang.org/x/mod v0.14.0
golang.org/x/mod v0.15.0
golang.org/x/sync v0.6.0
golang.org/x/telemetry v0.0.0-20240201224847-0a1d30dda509
golang.org/x/telemetry v0.0.0-20240209200032-7b892fcb8a78
golang.org/x/text v0.14.0
golang.org/x/tools v0.17.1-0.20240206204217-56dc8684fb5a
golang.org/x/vuln v1.0.1
Expand All @@ -22,7 +22,9 @@ require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/google/safehtml v0.1.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/sys v0.17.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect

)

replace golang.org/x/tools => ../

0 comments on commit c2dba44

Please sign in to comment.