Skip to content

Commit 61c1b28

Browse files
committed
go/analysis/passes/modernize: newexpr: add //go:fix inline directives
This CL causes the newexpr suggested fix to add "inline" directives on the function equivalent to new(expr) so that calls to it are eventually melted away. This is safe because the inliner now checks that the caller's Go version is at least as new as the callee's. Updates golang/go#45624 Updates golang/go#75726 Change-Id: I36d27c7fa92965340da739ab71ed0cddff0d03ce Reviewed-on: https://go-review.googlesource.com/c/tools/+/716561 Auto-Submit: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Findley <rfindley@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent eebe4d7 commit 61c1b28

File tree

5 files changed

+28
-23
lines changed

5 files changed

+28
-23
lines changed

go/analysis/passes/modernize/doc.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,12 @@ This analyzer finds declarations of functions of this form:
176176
and suggests a fix to turn them into inlinable wrappers around
177177
go1.26's built-in new(expr) function:
178178
179+
//go:fix inline
179180
func varOf(x int) *int { return new(x) }
180181
182+
(The directive comment causes the 'inline' analyzer to suggest
183+
that calls to such functions are inlined.)
184+
181185
In addition, this analyzer suggests a fix for each call
182186
to one of the functions before it is transformed, so that
183187
@@ -187,9 +191,9 @@ is replaced by:
187191
188192
use(new(123))
189193
190-
(Wrapper functions such as varOf are common when working with Go
194+
Wrapper functions such as varOf are common when working with Go
191195
serialization packages such as for JSON or protobuf, where pointers
192-
are often used to express optionality.)
196+
are often used to express optionality.
193197
194198
# Analyzer omitzero
195199

go/analysis/passes/modernize/newexpr.go

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,25 +87,18 @@ func run(pass *analysis.Pass) (any, error) {
8787
}
8888
}
8989

90-
// Disabled until we resolve https://go.dev/issue/75726
91-
// (Go version skew between caller and callee in inliner.)
92-
// TODO(adonovan): fix and reenable.
90+
// Add a //go:fix inline annotation, if not already present.
9391
//
94-
// Also, restore these lines to our section of doc.go:
95-
// //go:fix inline
96-
// ...
97-
// (The directive comment causes the inline analyzer to suggest
98-
// that calls to such functions are inlined.)
99-
if false {
100-
// Add a //go:fix inline annotation, if not already present.
101-
// TODO(adonovan): use ast.ParseDirective when go1.26 is assured.
102-
if !strings.Contains(decl.Doc.Text(), "go:fix inline") {
103-
edits = append(edits, analysis.TextEdit{
104-
Pos: decl.Pos(),
105-
End: decl.Pos(),
106-
NewText: []byte("//go:fix inline\n"),
107-
})
108-
}
92+
// The inliner will not inline a newer callee body into an
93+
// older Go file; see https://go.dev/issue/75726.
94+
//
95+
// TODO(adonovan): use ast.ParseDirective when go1.26 is assured.
96+
if !strings.Contains(decl.Doc.Text(), "go:fix inline") {
97+
edits = append(edits, analysis.TextEdit{
98+
Pos: decl.Pos(),
99+
End: decl.Pos(),
100+
NewText: []byte("//go:fix inline\n"),
101+
})
109102
}
110103

111104
if len(edits) > 0 {

go/analysis/passes/modernize/testdata/src/newexpr/newexpr.go.golden

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
package newexpr
44

55
// intVar returns a new var whose value is i.
6+
//
7+
//go:fix inline
68
func intVar(i int) *int { return new(i) } // want `intVar can be an inlinable wrapper around new\(expr\)` intVar:"newlike"
79

10+
//go:fix inline
811
func int64Var(i int64) *int64 { return new(i) } // want `int64Var can be an inlinable wrapper around new\(expr\)` int64Var:"newlike"
912

13+
//go:fix inline
1014
func stringVar(s string) *string { return new(s) } // want `stringVar can be an inlinable wrapper around new\(expr\)` stringVar:"newlike"
1115

16+
//go:fix inline
1217
func varOf[T any](x T) *T { return new(x) } // want `varOf can be an inlinable wrapper around new\(expr\)` varOf:"newlike"
1318

1419
var (

gopls/doc/analyzers.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3469,8 +3469,11 @@ This analyzer finds declarations of functions of this form:
34693469

34703470
and suggests a fix to turn them into inlinable wrappers around go1.26's built-in new(expr) function:
34713471

3472+
//go:fix inline
34723473
func varOf(x int) *int { return new(x) }
34733474

3475+
(The directive comment causes the 'inline' analyzer to suggest that calls to such functions are inlined.)
3476+
34743477
In addition, this analyzer suggests a fix for each call to one of the functions before it is transformed, so that
34753478

34763479
use(varOf(123))
@@ -3479,7 +3482,7 @@ is replaced by:
34793482

34803483
use(new(123))
34813484

3482-
(Wrapper functions such as varOf are common when working with Go serialization packages such as for JSON or protobuf, where pointers are often used to express optionality.)
3485+
Wrapper functions such as varOf are common when working with Go serialization packages such as for JSON or protobuf, where pointers are often used to express optionality.
34833486

34843487

34853488
Default: on.

gopls/internal/doc/api.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,7 @@
15461546
},
15471547
{
15481548
"Name": "\"newexpr\"",
1549-
"Doc": "simplify code by using go1.26's new(expr)\n\nThis analyzer finds declarations of functions of this form:\n\n\tfunc varOf(x int) *int { return \u0026x }\n\nand suggests a fix to turn them into inlinable wrappers around\ngo1.26's built-in new(expr) function:\n\n\tfunc varOf(x int) *int { return new(x) }\n\nIn addition, this analyzer suggests a fix for each call\nto one of the functions before it is transformed, so that\n\n\tuse(varOf(123))\n\nis replaced by:\n\n\tuse(new(123))\n\n(Wrapper functions such as varOf are common when working with Go\nserialization packages such as for JSON or protobuf, where pointers\nare often used to express optionality.)",
1549+
"Doc": "simplify code by using go1.26's new(expr)\n\nThis analyzer finds declarations of functions of this form:\n\n\tfunc varOf(x int) *int { return \u0026x }\n\nand suggests a fix to turn them into inlinable wrappers around\ngo1.26's built-in new(expr) function:\n\n\t//go:fix inline\n\tfunc varOf(x int) *int { return new(x) }\n\n(The directive comment causes the 'inline' analyzer to suggest\nthat calls to such functions are inlined.)\n\nIn addition, this analyzer suggests a fix for each call\nto one of the functions before it is transformed, so that\n\n\tuse(varOf(123))\n\nis replaced by:\n\n\tuse(new(123))\n\nWrapper functions such as varOf are common when working with Go\nserialization packages such as for JSON or protobuf, where pointers\nare often used to express optionality.",
15501550
"Default": "true",
15511551
"Status": ""
15521552
},
@@ -3449,7 +3449,7 @@
34493449
},
34503450
{
34513451
"Name": "newexpr",
3452-
"Doc": "simplify code by using go1.26's new(expr)\n\nThis analyzer finds declarations of functions of this form:\n\n\tfunc varOf(x int) *int { return \u0026x }\n\nand suggests a fix to turn them into inlinable wrappers around\ngo1.26's built-in new(expr) function:\n\n\tfunc varOf(x int) *int { return new(x) }\n\nIn addition, this analyzer suggests a fix for each call\nto one of the functions before it is transformed, so that\n\n\tuse(varOf(123))\n\nis replaced by:\n\n\tuse(new(123))\n\n(Wrapper functions such as varOf are common when working with Go\nserialization packages such as for JSON or protobuf, where pointers\nare often used to express optionality.)",
3452+
"Doc": "simplify code by using go1.26's new(expr)\n\nThis analyzer finds declarations of functions of this form:\n\n\tfunc varOf(x int) *int { return \u0026x }\n\nand suggests a fix to turn them into inlinable wrappers around\ngo1.26's built-in new(expr) function:\n\n\t//go:fix inline\n\tfunc varOf(x int) *int { return new(x) }\n\n(The directive comment causes the 'inline' analyzer to suggest\nthat calls to such functions are inlined.)\n\nIn addition, this analyzer suggests a fix for each call\nto one of the functions before it is transformed, so that\n\n\tuse(varOf(123))\n\nis replaced by:\n\n\tuse(new(123))\n\nWrapper functions such as varOf are common when working with Go\nserialization packages such as for JSON or protobuf, where pointers\nare often used to express optionality.",
34533453
"URL": "https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize#newexpr",
34543454
"Default": true
34553455
},

0 commit comments

Comments
 (0)