Skip to content

Commit 28beb2d

Browse files
committed
all: merge master (53e637b) into gopls-release-branch.0.14
Also add back the replace directive. For golang/go#63220 Merge List: + 2023-10-16 53e637b internal/refactor/inline: improve check for last uses of free vars + 2023-10-16 61bb3e9 internal/refactor/inline: less hacky solution for eliding braces + 2023-10-16 8a71c39 gopls/internal/lsp/source: abort change signature on overlapping calls + 2023-10-16 f744e4b go/ssa: propagate goversions in ssa + 2023-10-16 6fcd778 gopls/internal/lsp: add code actions to remove unused parameters + 2023-10-16 918e96a internal/refactor/inline: use binding decl with literalization + 2023-10-13 12b5dad gopls: deprecate "tempModfile" and "expandWorkspaceToModule" settings + 2023-10-12 f85b3f7 internal/refactor/inline: don't treat blanks as decls in declares() + 2023-10-12 3484534 internal/refactor/inline: docs for 0.14 release notes + 2023-10-11 b9b97d9 go/types/objectpath: remove method sorting Change-Id: I371204ec58877fcfaa03f7ba663a6b5718b8ecf0
2 parents 586b412 + 53e637b commit 28beb2d

Some content is hidden

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

53 files changed

+2194
-311
lines changed

go/analysis/unitchecker/unitchecker.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re
319319
analyzers = filtered
320320

321321
// Read facts from imported packages.
322-
facts, err := facts.NewDecoder(pkg).Decode(false, makeFactImporter(cfg))
322+
facts, err := facts.NewDecoder(pkg).Decode(makeFactImporter(cfg))
323323
if err != nil {
324324
return nil, err
325325
}
@@ -418,7 +418,7 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re
418418
results[i].diagnostics = act.diagnostics
419419
}
420420

421-
data := facts.Encode(false)
421+
data := facts.Encode()
422422
if err := exportFacts(cfg, data); err != nil {
423423
return nil, fmt.Errorf("failed to export analysis facts: %v", err)
424424
}

go/ssa/builder.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,8 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
647647
typeparams: fn.typeparams, // share the parent's type parameters.
648648
typeargs: fn.typeargs, // share the parent's type arguments.
649649
info: fn.info,
650-
subst: fn.subst, // share the parent's type substitutions.
650+
subst: fn.subst, // share the parent's type substitutions.
651+
goversion: fn.goversion, // share the parent's goversion
651652
}
652653
fn.AnonFuncs = append(fn.AnonFuncs, fn2)
653654
b.created.Add(fn2)
@@ -2516,11 +2517,18 @@ func (p *Package) build() {
25162517
if len(p.info.InitOrder) > 0 && len(p.files) == 0 {
25172518
panic("no source files provided for package. cannot initialize globals")
25182519
}
2520+
25192521
for _, varinit := range p.info.InitOrder {
25202522
if init.Prog.mode&LogSource != 0 {
25212523
fmt.Fprintf(os.Stderr, "build global initializer %v @ %s\n",
25222524
varinit.Lhs, p.Prog.Fset.Position(varinit.Rhs.Pos()))
25232525
}
2526+
// Initializers for global vars are evaluated in dependency
2527+
// order, but may come from arbitrary files of the package
2528+
// with different versions, so we transiently update
2529+
// init.goversion for each one. (Since init is a synthetic
2530+
// function it has no syntax of its own that needs a version.)
2531+
init.goversion = p.initVersion[varinit.Rhs]
25242532
if len(varinit.Lhs) == 1 {
25252533
// 1:1 initialization: var x, y = a(), b()
25262534
var lval lvalue
@@ -2541,6 +2549,7 @@ func (p *Package) build() {
25412549
}
25422550
}
25432551
}
2552+
init.goversion = "" // The rest of the init function is synthetic. No syntax => no goversion.
25442553

25452554
// Call all of the declared init() functions in source order.
25462555
for _, file := range p.files {
@@ -2585,8 +2594,11 @@ func (p *Package) build() {
25852594
b.needsRuntimeTypes() // Add all of the runtime type information. May CREATE Functions.
25862595
}
25872596

2588-
p.info = nil // We no longer need ASTs or go/types deductions.
2589-
p.created = nil // We no longer need created functions.
2597+
// We no longer need transient information: ASTs or go/types deductions.
2598+
p.info = nil
2599+
p.created = nil
2600+
p.files = nil
2601+
p.initVersion = nil
25902602

25912603
if p.Prog.mode&SanityCheckFunctions != 0 {
25922604
sanityCheckPackage(p)

go/ssa/builder_go122_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2023 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build go1.22
6+
// +build go1.22
7+
8+
package ssa_test
9+
10+
import (
11+
"go/ast"
12+
"go/parser"
13+
"go/token"
14+
"go/types"
15+
"testing"
16+
17+
"golang.org/x/tools/go/ssa"
18+
"golang.org/x/tools/go/ssa/ssautil"
19+
)
20+
21+
func TestMultipleGoversions(t *testing.T) {
22+
var contents = map[string]string{
23+
"post.go": `
24+
//go:build go1.22
25+
package p
26+
27+
var distinct = func(l []int) []*int {
28+
var r []*int
29+
for i := range l {
30+
r = append(r, &i)
31+
}
32+
return r
33+
}(l)
34+
`,
35+
"pre.go": `
36+
package p
37+
38+
var l = []int{0, 0, 0}
39+
40+
var same = func(l []int) []*int {
41+
var r []*int
42+
for i := range l {
43+
r = append(r, &i)
44+
}
45+
return r
46+
}(l)
47+
`,
48+
}
49+
50+
fset := token.NewFileSet()
51+
var files []*ast.File
52+
for _, fname := range []string{"post.go", "pre.go"} {
53+
file, err := parser.ParseFile(fset, fname, contents[fname], 0)
54+
if err != nil {
55+
t.Fatal(err)
56+
}
57+
files = append(files, file)
58+
}
59+
60+
pkg := types.NewPackage("p", "")
61+
conf := &types.Config{Importer: nil, GoVersion: "go1.21"}
62+
p, _, err := ssautil.BuildPackage(conf, fset, pkg, files, ssa.SanityCheckFunctions)
63+
if err != nil {
64+
t.Errorf("unexpected error: %v", err)
65+
}
66+
67+
fns := ssautil.AllFunctions(p.Prog)
68+
names := make(map[string]*ssa.Function)
69+
for fn := range fns {
70+
names[fn.String()] = fn
71+
}
72+
for _, item := range []struct{ name, wantSyn, wantPos string }{
73+
{"p.init", "package initializer", "-"},
74+
{"p.init$1", "", "post.go:5:17"},
75+
{"p.init$2", "", "pre.go:6:13"},
76+
} {
77+
fn := names[item.name]
78+
if fn == nil {
79+
t.Fatalf("Could not find function named %q in package %s", item.name, p)
80+
}
81+
if fn.Synthetic != item.wantSyn {
82+
t.Errorf("Function %q.Syntethic=%q. expected %q", fn, fn.Synthetic, item.wantSyn)
83+
}
84+
if got := fset.Position(fn.Pos()).String(); got != item.wantPos {
85+
t.Errorf("Function %q.Pos()=%q. expected %q", fn, got, item.wantPos)
86+
}
87+
}
88+
}

go/ssa/create.go

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,10 @@ func NewProgram(fset *token.FileSet, mode BuilderMode) *Program {
4747
// typechecker object obj.
4848
//
4949
// For objects from Go source code, syntax is the associated syntax
50-
// tree (for funcs and vars only); it will be used during the build
50+
// tree (for funcs and vars only) and goversion defines the
51+
// appropriate interpretation; they will be used during the build
5152
// phase.
52-
func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node) {
53+
func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node, goversion string) {
5354
name := obj.Name()
5455
switch obj := obj.(type) {
5556
case *types.Builtin:
@@ -108,6 +109,7 @@ func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node) {
108109
Prog: pkg.Prog,
109110
typeparams: tparams,
110111
info: pkg.info,
112+
goversion: goversion,
111113
}
112114
pkg.created.Add(fn)
113115
if syntax == nil {
@@ -130,24 +132,27 @@ func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node) {
130132
// membersFromDecl populates package pkg with members for each
131133
// typechecker object (var, func, const or type) associated with the
132134
// specified decl.
133-
func membersFromDecl(pkg *Package, decl ast.Decl) {
135+
func membersFromDecl(pkg *Package, decl ast.Decl, goversion string) {
134136
switch decl := decl.(type) {
135137
case *ast.GenDecl: // import, const, type or var
136138
switch decl.Tok {
137139
case token.CONST:
138140
for _, spec := range decl.Specs {
139141
for _, id := range spec.(*ast.ValueSpec).Names {
140142
if !isBlankIdent(id) {
141-
memberFromObject(pkg, pkg.info.Defs[id], nil)
143+
memberFromObject(pkg, pkg.info.Defs[id], nil, "")
142144
}
143145
}
144146
}
145147

146148
case token.VAR:
147149
for _, spec := range decl.Specs {
150+
for _, rhs := range spec.(*ast.ValueSpec).Values {
151+
pkg.initVersion[rhs] = goversion
152+
}
148153
for _, id := range spec.(*ast.ValueSpec).Names {
149154
if !isBlankIdent(id) {
150-
memberFromObject(pkg, pkg.info.Defs[id], spec)
155+
memberFromObject(pkg, pkg.info.Defs[id], spec, goversion)
151156
}
152157
}
153158
}
@@ -156,15 +161,15 @@ func membersFromDecl(pkg *Package, decl ast.Decl) {
156161
for _, spec := range decl.Specs {
157162
id := spec.(*ast.TypeSpec).Name
158163
if !isBlankIdent(id) {
159-
memberFromObject(pkg, pkg.info.Defs[id], nil)
164+
memberFromObject(pkg, pkg.info.Defs[id], nil, "")
160165
}
161166
}
162167
}
163168

164169
case *ast.FuncDecl:
165170
id := decl.Name
166171
if !isBlankIdent(id) {
167-
memberFromObject(pkg, pkg.info.Defs[id], decl)
172+
memberFromObject(pkg, pkg.info.Defs[id], decl, goversion)
168173
}
169174
}
170175
}
@@ -197,8 +202,10 @@ func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *
197202
Members: make(map[string]Member),
198203
objects: make(map[types.Object]Member),
199204
Pkg: pkg,
200-
info: info, // transient (CREATE and BUILD phases)
201-
files: files, // transient (CREATE and BUILD phases)
205+
// transient values (CREATE and BUILD phases)
206+
info: info,
207+
files: files,
208+
initVersion: make(map[ast.Expr]string),
202209
}
203210

204211
// Add init() function.
@@ -209,6 +216,7 @@ func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *
209216
Pkg: p,
210217
Prog: prog,
211218
info: p.info,
219+
goversion: "", // See Package.build() for details.
212220
}
213221
p.Members[p.init.name] = p.init
214222
p.created.Add(p.init)
@@ -218,8 +226,9 @@ func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *
218226
if len(files) > 0 {
219227
// Go source package.
220228
for _, file := range files {
229+
goversion := goversionOf(p, file)
221230
for _, decl := range file.Decls {
222-
membersFromDecl(p, decl)
231+
membersFromDecl(p, decl, goversion)
223232
}
224233
}
225234
} else {
@@ -229,11 +238,11 @@ func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *
229238
scope := p.Pkg.Scope()
230239
for _, name := range scope.Names() {
231240
obj := scope.Lookup(name)
232-
memberFromObject(p, obj, nil)
241+
memberFromObject(p, obj, nil, "")
233242
if obj, ok := obj.(*types.TypeName); ok {
234243
if named, ok := obj.Type().(*types.Named); ok {
235244
for i, n := 0, named.NumMethods(); i < n; i++ {
236-
memberFromObject(p, named.Method(i), nil)
245+
memberFromObject(p, named.Method(i), nil, "")
237246
}
238247
}
239248
}

go/ssa/func.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ func (f *Function) finishBody() {
324324
f.namedResults = nil // (used by lifting)
325325
f.info = nil
326326
f.subst = nil
327+
f.goversion = ""
327328

328329
numberRegisters(f) // uses f.namedRegisters
329330
}

go/ssa/instantiate.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ type instanceSet struct {
3232
fn *Function // fn.typeparams.Len() > 0 and len(fn.typeargs) == 0.
3333
instances map[*typeList]*Function // canonical type arguments to an instance.
3434
syntax *ast.FuncDecl // fn.syntax copy for instantiating after fn is done. nil on synthetic packages.
35-
info *types.Info // fn.pkg.info copy for building after fn is done.. nil on synthetic packages.
36-
35+
info *types.Info // fn.pkg.info copy for building after fn is done. nil on synthetic packages.
36+
goversion string // goversion to build syntax with.
3737
// TODO(taking): Consider ways to allow for clearing syntax and info when done building.
3838
// May require a public API change as MethodValue can request these be built after prog.Build() is done.
3939
}
@@ -66,9 +66,10 @@ func (prog *Program) createInstanceSet(fn *Function) {
6666

6767
if _, ok := prog.instances[fn]; !ok {
6868
prog.instances[fn] = &instanceSet{
69-
fn: fn,
70-
syntax: syntax,
71-
info: fn.info,
69+
fn: fn,
70+
syntax: syntax,
71+
info: fn.info,
72+
goversion: fn.goversion,
7273
}
7374
}
7475
}
@@ -169,8 +170,8 @@ func (insts *instanceSet) lookupOrCreate(targs []types.Type, parameterized *tpWa
169170
typeargs: targs,
170171
info: insts.info, // on synthetic packages info is nil.
171172
subst: subst,
173+
goversion: insts.goversion,
172174
}
173-
174175
cr.Add(instance)
175176
insts.instances[key] = instance
176177
return instance

go/ssa/source.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ package ssa
1111
// the originating syntax, as specified.
1212

1313
import (
14+
"fmt"
1415
"go/ast"
1516
"go/token"
1617
"go/types"
@@ -131,6 +132,31 @@ func findNamedFunc(pkg *Package, pos token.Pos) *Function {
131132
return nil
132133
}
133134

135+
// goversionOf returns the goversion of a node in the package
136+
// where the node is either a function declaration or the initial
137+
// value of a package level variable declaration.
138+
func goversionOf(p *Package, file *ast.File) string {
139+
if p.info == nil {
140+
return ""
141+
}
142+
143+
// TODO(taking): Update to the following when internal/versions available:
144+
// return versions.Lang(versions.FileVersions(p.info, file))
145+
return fileVersions(file)
146+
}
147+
148+
// TODO(taking): Remove when internal/versions is available.
149+
var fileVersions = func(file *ast.File) string { return "" }
150+
151+
// parses a goXX.YY version or returns a negative version on an error.
152+
// TODO(taking): Switch to a permanent solution when internal/versions is submitted.
153+
func parseGoVersion(x string) (major, minor int) {
154+
if _, err := fmt.Sscanf(x, "go%d.%d", &major, &minor); err != nil || major < 0 || minor < 0 {
155+
return -1, -1
156+
}
157+
return
158+
}
159+
134160
// ValueForExpr returns the SSA Value that corresponds to non-constant
135161
// expression e.
136162
//

go/ssa/ssa.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,12 @@ type Package struct {
5757

5858
// The following fields are set transiently, then cleared
5959
// after building.
60-
buildOnce sync.Once // ensures package building occurs once
61-
ninit int32 // number of init functions
62-
info *types.Info // package type information
63-
files []*ast.File // package ASTs
64-
created creator // members created as a result of building this package (includes declared functions, wrappers)
60+
buildOnce sync.Once // ensures package building occurs once
61+
ninit int32 // number of init functions
62+
info *types.Info // package type information
63+
files []*ast.File // package ASTs
64+
created creator // members created as a result of building this package (includes declared functions, wrappers)
65+
initVersion map[ast.Expr]string // goversion to use for each global var init expr
6566
}
6667

6768
// A Member is a member of a Go package, implemented by *NamedConst,
@@ -338,6 +339,7 @@ type Function struct {
338339
lblocks map[types.Object]*lblock // labelled blocks
339340
info *types.Info // *types.Info to build from. nil for wrappers.
340341
subst *subster // non-nil => expand generic body using this type substitution of ground types
342+
goversion string // Go version of syntax (NB: init is special)
341343
}
342344

343345
// BasicBlock represents an SSA basic block.

go/ssa/ssautil/load.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, fil
147147
Selections: make(map[*ast.SelectorExpr]*types.Selection),
148148
}
149149
typeparams.InitInstanceInfo(info)
150+
// versions.InitFileVersions(info) // TODO(taking): Enable when internal/versions is available.
150151
if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil {
151152
return nil, nil, err
152153
}

0 commit comments

Comments
 (0)