Skip to content

Commit 451716b

Browse files
committed
internal/refactor/inline: consider "", 0.0, 1.0 duplicable
There is a certain amount of arbitrariness, but these constants are common, fundamental, and short. Change-Id: I198e8dbb511d25d969e35a4308108dcf89f79bb0 Reviewed-on: https://go-review.googlesource.com/c/tools/+/531696 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Alan Donovan <[email protected]>
1 parent 792f91f commit 451716b

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

internal/refactor/inline/inline.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"bytes"
99
"fmt"
1010
"go/ast"
11+
"go/constant"
1112
"go/format"
1213
"go/parser"
1314
"go/token"
@@ -1816,17 +1817,30 @@ func duplicable(info *types.Info, e ast.Expr) bool {
18161817
switch e := e.(type) {
18171818
case *ast.ParenExpr:
18181819
return duplicable(info, e.X)
1820+
18191821
case *ast.Ident:
18201822
return true
1823+
18211824
case *ast.BasicLit:
1822-
return e.Kind == token.INT
1825+
v := info.Types[e].Value
1826+
switch e.Kind {
1827+
case token.INT:
1828+
return true // any int
1829+
case token.STRING:
1830+
return consteq(v, kZeroString) // only ""
1831+
case token.FLOAT:
1832+
return consteq(v, kZeroFloat) || consteq(v, kOneFloat) // only 0.0 or 1.0
1833+
}
1834+
18231835
case *ast.UnaryExpr: // e.g. +1, -1
18241836
return (e.Op == token.ADD || e.Op == token.SUB) && duplicable(info, e.X)
1837+
18251838
case *ast.CallExpr:
18261839
// Don't treat a conversion T(x) as duplicable even
18271840
// if x is duplicable because it could duplicate
18281841
// allocations. There may be cases to tease apart here.
18291842
return false
1843+
18301844
case *ast.SelectorExpr:
18311845
if sel, ok := info.Selections[e]; ok {
18321846
// A field or method selection x.f is referentially
@@ -1835,11 +1849,21 @@ func duplicable(info *types.Info, e ast.Expr) bool {
18351849
}
18361850
// A qualified identifier pkg.Name is referentially transparent.
18371851
return true
1838-
default:
1839-
return false
18401852
}
1853+
return false
1854+
}
1855+
1856+
func consteq(x, y constant.Value) bool {
1857+
return constant.Compare(x, token.EQL, y)
18411858
}
18421859

1860+
var (
1861+
kZeroInt = constant.MakeInt64(0)
1862+
kZeroString = constant.MakeString("")
1863+
kZeroFloat = constant.MakeFloat64(0.0)
1864+
kOneFloat = constant.MakeFloat64(1.0)
1865+
)
1866+
18431867
// -- inline helpers --
18441868

18451869
func assert(cond bool, msg string) {

internal/refactor/inline/inline_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -376,10 +376,10 @@ func TestBasics(t *testing.T) {
376376
{
377377
"Non-duplicable arguments are not substituted even if pure.",
378378
`func f(s string, i int) { print(s, s, i, i) }`,
379-
`func _() { f("", 0) }`,
379+
`func _() { f("hi", 0) }`,
380380
`func _() {
381381
{
382-
var s string = ""
382+
var s string = "hi"
383383
print(s, s, 0, 0)
384384
}
385385
}`,
@@ -777,11 +777,11 @@ func TestNamedResultVars(t *testing.T) {
777777
{
778778
"Ditto, with binding decl again.",
779779
`func f(y string) (x int) { return x+x+len(y+y) }`,
780-
`func _() { f("") }`,
780+
`func _() { f(".") }`,
781781
`func _() {
782782
{
783783
var (
784-
y string = ""
784+
y string = "."
785785
x int
786786
)
787787
_ = x + x + len(y+y)
@@ -792,11 +792,11 @@ func TestNamedResultVars(t *testing.T) {
792792
{
793793
"Ditto, with binding decl (due to repeated y refs).",
794794
`func f(y string) (x string) { return x+y+y }`,
795-
`func _() { f("") }`,
795+
`func _() { f(".") }`,
796796
`func _() {
797797
{
798798
var (
799-
y string = ""
799+
y string = "."
800800
x string
801801
)
802802
_ = x + y + y
@@ -835,8 +835,8 @@ func TestNamedResultVars(t *testing.T) {
835835
{
836836
"Shadowing in binding decl for named results => literalization.",
837837
`func f(y string) (x y) { return x+x+len(y+y) }; type y = int`,
838-
`func _() { f("") }`,
839-
`func _() { func(y string) (x y) { return x + x + len(y+y) }("") }`,
838+
`func _() { f(".") }`,
839+
`func _() { func(y string) (x y) { return x + x + len(y+y) }(".") }`,
840840
},
841841
})
842842
}

0 commit comments

Comments
 (0)