Skip to content

Commit c2dba44

Browse files
committed
all: merge master (1b39a8b) into gopls-release-branch.0.15
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
2 parents 9f736d6 + 1b39a8b commit c2dba44

File tree

45 files changed

+793
-121
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+793
-121
lines changed

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ go 1.18
44

55
require (
66
github.com/yuin/goldmark v1.4.13
7-
golang.org/x/mod v0.14.0
8-
golang.org/x/net v0.20.0
7+
golang.org/x/mod v0.15.0
8+
golang.org/x/net v0.21.0
99
)
1010

1111
require golang.org/x/sync v0.6.0
1212

1313
require (
14-
golang.org/x/sys v0.16.0 // indirect
15-
golang.org/x/telemetry v0.0.0-20240201224847-0a1d30dda509
14+
golang.org/x/sys v0.17.0 // indirect
15+
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808
1616
)

go.sum

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
22
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
3-
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
4-
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
5-
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
6-
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
3+
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
4+
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
5+
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
6+
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
77
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
88
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
9-
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
10-
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
9+
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
10+
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
1111
golang.org/x/telemetry v0.0.0-20240201224847-0a1d30dda509 h1:Nr7eTQpQZ/ytesxDJpQgaf0t4sdLnnDtAbmtViTrSUo=
1212
golang.org/x/telemetry v0.0.0-20240201224847-0a1d30dda509/go.mod h1:ZthVHHkOi8rlMEsfFr3Ie42Ym1NonbFNNRKW3ci0UrU=
13+
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808 h1:+Kc94D8UVEVxJnLXp/+FMfqQARZtWHfVrcRtcG8aT3g=
14+
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ=

go/analysis/analysistest/analysistest.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"os"
1616
"path/filepath"
1717
"regexp"
18+
"runtime"
1819
"sort"
1920
"strconv"
2021
"strings"
@@ -128,6 +129,19 @@ type Testing interface {
128129
func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns ...string) []*Result {
129130
r := Run(t, dir, a, patterns...)
130131

132+
// If the immediate caller of RunWithSuggestedFixes is in
133+
// x/tools, we apply stricter checks as required by gopls.
134+
inTools := false
135+
{
136+
var pcs [1]uintptr
137+
n := runtime.Callers(1, pcs[:])
138+
frames := runtime.CallersFrames(pcs[:n])
139+
fr, _ := frames.Next()
140+
if fr.Func != nil && strings.HasPrefix(fr.Func.Name(), "golang.org/x/tools/") {
141+
inTools = true
142+
}
143+
}
144+
131145
// Process each result (package) separately, matching up the suggested
132146
// fixes into a diff, which we will compare to the .golden file. We have
133147
// to do this per-result in case a file appears in two packages, such as in
@@ -145,8 +159,14 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
145159

146160
// Validate edits, prepare the fileEdits map and read the file contents.
147161
for _, diag := range act.Diagnostics {
148-
for _, sf := range diag.SuggestedFixes {
149-
for _, edit := range sf.TextEdits {
162+
for _, fix := range diag.SuggestedFixes {
163+
164+
// Assert that lazy fixes have a Category (#65578, #65087).
165+
if inTools && len(fix.TextEdits) == 0 && diag.Category == "" {
166+
t.Errorf("missing Diagnostic.Category for SuggestedFix without TextEdits (gopls requires the category for the name of the fix command")
167+
}
168+
169+
for _, edit := range fix.TextEdits {
150170
start, end := edit.Pos, edit.End
151171
if !end.IsValid() {
152172
end = start
@@ -175,7 +195,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
175195
if _, ok := fileEdits[file]; !ok {
176196
fileEdits[file] = make(map[string][]diff.Edit)
177197
}
178-
fileEdits[file][sf.Message] = append(fileEdits[file][sf.Message], diff.Edit{
198+
fileEdits[file][fix.Message] = append(fileEdits[file][fix.Message], diff.Edit{
179199
Start: file.Offset(start),
180200
End: file.Offset(end),
181201
New: string(edit.NewText),

go/analysis/passes/deepequalerrors/deepequalerrors.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
1616
"golang.org/x/tools/go/ast/inspector"
1717
"golang.org/x/tools/go/types/typeutil"
18+
"golang.org/x/tools/internal/aliases"
1819
)
1920

2021
const Doc = `check for calls of reflect.DeepEqual on error values
@@ -101,7 +102,8 @@ func containsError(typ types.Type) bool {
101102
return true
102103
}
103104
}
104-
case *types.Named:
105+
case *types.Named,
106+
*aliases.Alias:
105107
return check(t.Underlying())
106108

107109
// We list the remaining valid type kinds for completeness.

go/analysis/passes/nilness/nilness.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,42 @@ func runFunc(pass *analysis.Pass, fn *ssa.Function) {
189189
}
190190
}
191191

192+
// In code of the form:
193+
//
194+
// if ptr, ok := x.(*T); ok { ... } else { fsucc }
195+
//
196+
// the fsucc block learns that ptr == nil,
197+
// since that's its zero value.
198+
if If, ok := b.Instrs[len(b.Instrs)-1].(*ssa.If); ok {
199+
// Handle "if ok" and "if !ok" variants.
200+
cond, fsucc := If.Cond, b.Succs[1]
201+
if unop, ok := cond.(*ssa.UnOp); ok && unop.Op == token.NOT {
202+
cond, fsucc = unop.X, b.Succs[0]
203+
}
204+
205+
// Match pattern:
206+
// t0 = typeassert (pointerlike)
207+
// t1 = extract t0 #0 // ptr
208+
// t2 = extract t0 #1 // ok
209+
// if t2 goto tsucc, fsucc
210+
if extract1, ok := cond.(*ssa.Extract); ok && extract1.Index == 1 {
211+
if assert, ok := extract1.Tuple.(*ssa.TypeAssert); ok &&
212+
isNillable(assert.AssertedType) {
213+
for _, pinstr := range *assert.Referrers() {
214+
if extract0, ok := pinstr.(*ssa.Extract); ok &&
215+
extract0.Index == 0 &&
216+
extract0.Tuple == extract1.Tuple {
217+
for _, d := range b.Dominees() {
218+
if len(d.Preds) == 1 && d == fsucc {
219+
visit(d, append(stack, fact{extract0, isnil}))
220+
}
221+
}
222+
}
223+
}
224+
}
225+
}
226+
}
227+
192228
for _, d := range b.Dominees() {
193229
visit(d, stack)
194230
}
@@ -360,3 +396,23 @@ func (ff facts) negate() facts {
360396
}
361397
return nn
362398
}
399+
400+
func is[T any](x any) bool {
401+
_, ok := x.(T)
402+
return ok
403+
}
404+
405+
func isNillable(t types.Type) bool {
406+
switch t := typeparams.CoreType(t).(type) {
407+
case *types.Pointer,
408+
*types.Map,
409+
*types.Signature,
410+
*types.Chan,
411+
*types.Interface,
412+
*types.Slice:
413+
return true
414+
case *types.Basic:
415+
return t == types.Typ[types.UnsafePointer]
416+
}
417+
return false
418+
}

go/analysis/passes/nilness/testdata/src/a/a.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,29 @@ func f14() {
216216
print(x)
217217
}
218218
}
219+
220+
func f15(x any) {
221+
ptr, ok := x.(*int)
222+
if ok {
223+
return
224+
}
225+
println(*ptr) // want "nil dereference in load"
226+
}
227+
228+
func f16(x any) {
229+
ptr, ok := x.(*int)
230+
if !ok {
231+
println(*ptr) // want "nil dereference in load"
232+
return
233+
}
234+
println(*ptr)
235+
}
236+
237+
func f18(x any) {
238+
ptr, ok := x.(*int)
239+
if ok {
240+
println(ptr)
241+
// falls through
242+
}
243+
println(*ptr)
244+
}

go/analysis/passes/stringintconv/string.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"golang.org/x/tools/go/analysis/passes/inspect"
1616
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
1717
"golang.org/x/tools/go/ast/inspector"
18+
"golang.org/x/tools/internal/aliases"
1819
"golang.org/x/tools/internal/typeparams"
1920
)
2021

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

195196
func structuralTypes(t types.Type) ([]types.Type, error) {
196197
var structuralTypes []types.Type
197-
switch t := t.(type) {
198-
case *types.TypeParam:
199-
terms, err := typeparams.StructuralTerms(t)
198+
if tp, ok := aliases.Unalias(t).(*types.TypeParam); ok {
199+
terms, err := typeparams.StructuralTerms(tp)
200200
if err != nil {
201201
return nil, err
202202
}
203203
for _, term := range terms {
204204
structuralTypes = append(structuralTypes, term.Type())
205205
}
206-
default:
206+
} else {
207207
structuralTypes = append(structuralTypes, t)
208208
}
209209
return structuralTypes, nil

go/types/typeutil/map.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"go/types"
1313
"reflect"
1414

15+
"golang.org/x/tools/internal/aliases"
1516
"golang.org/x/tools/internal/typeparams"
1617
)
1718

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

263+
case *aliases.Alias:
264+
return h.Hash(t.Underlying())
265+
262266
case *types.Array:
263267
return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem())
264268

@@ -457,6 +461,9 @@ func (h Hasher) shallowHash(t types.Type) uint32 {
457461
// elements (mostly Slice, Pointer, Basic, Named),
458462
// so there's no need to optimize anything else.
459463
switch t := t.(type) {
464+
case *aliases.Alias:
465+
return h.shallowHash(t.Underlying())
466+
460467
case *types.Signature:
461468
var hash uint32 = 604171
462469
if t.Variadic() {

go/types/typeutil/map_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,15 @@ var Issue56048 = Issue56048_I.m
247247
type Issue56048_Ib interface{ m() chan []*interface { Issue56048_Ib } }
248248
var Issue56048b = Issue56048_Ib.m
249249
250+
// Non-generic alias
251+
type NonAlias int
252+
type Alias1 = NonAlias
253+
type Alias2 = NonAlias
254+
255+
// Generic alias (requires go1.23)
256+
// type SetOfInt = map[int]bool
257+
// type Set[T comparable] = map[K]bool
258+
// type SetOfInt2 = Set[int]
250259
`
251260

252261
fset := token.NewFileSet()
@@ -307,6 +316,16 @@ var Issue56048b = Issue56048_Ib.m
307316
Quux = scope.Lookup("Quux").Type()
308317
Issue56048 = scope.Lookup("Issue56048").Type()
309318
Issue56048b = scope.Lookup("Issue56048b").Type()
319+
320+
// In go1.23 these will be *types.Alias; for now they are all int.
321+
NonAlias = scope.Lookup("NonAlias").Type()
322+
Alias1 = scope.Lookup("Alias1").Type()
323+
Alias2 = scope.Lookup("Alias2").Type()
324+
325+
// Requires go1.23.
326+
// SetOfInt = scope.Lookup("SetOfInt").Type()
327+
// Set = scope.Lookup("Set").Type().(*types.Alias)
328+
// SetOfInt2 = scope.Lookup("SetOfInt2").Type()
310329
)
311330

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

380399
{Issue56048, "Issue56048", true}, // (not actually about generics)
381400
{Issue56048b, "Issue56048b", true}, // (not actually about generics)
401+
402+
// All three types are identical.
403+
{NonAlias, "NonAlias", true},
404+
{Alias1, "Alias1", false},
405+
{Alias2, "Alias2", false},
406+
407+
// Generic aliases: requires go1.23.
408+
// {SetOfInt, "SetOfInt", true},
409+
// {Set, "Set", false},
410+
// {SetOfInt2, "SetOfInt2", false},
382411
}
383412

384413
for _, step := range steps {

go/types/typeutil/methodsetcache.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ package typeutil
99
import (
1010
"go/types"
1111
"sync"
12+
13+
"golang.org/x/tools/internal/aliases"
1214
)
1315

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

35-
switch T := T.(type) {
37+
switch T := aliases.Unalias(T).(type) {
3638
case *types.Named:
3739
return cache.lookupNamed(T).value
3840

3941
case *types.Pointer:
40-
if N, ok := T.Elem().(*types.Named); ok {
42+
if N, ok := aliases.Unalias(T.Elem()).(*types.Named); ok {
4143
return cache.lookupNamed(N).pointer
4244
}
4345
}

0 commit comments

Comments
 (0)