Skip to content

Commit 0c01408

Browse files
findleyrgopherbot
authored andcommitted
internal/refactor/inline: avoid binding decl for name used by other args
When inlining, a removed argument does not contain the last use of a name if that name is also used by another arg that is referenced by the callee. Implementing this logic improved a test case for golang/go#65217. For golang/go#65217 Change-Id: I486306f4ed57d759d5ab65bb390db5e81332d3ef Reviewed-on: https://go-review.googlesource.com/c/tools/+/629295 Auto-Submit: Robert Findley <rfindley@google.com> Reviewed-by: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent 63e03c3 commit 0c01408

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

gopls/internal/test/marker/testdata/codeaction/removeparam_issue65217.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ func _() {
4848

4949
func _() {
5050
var s S
51-
var _ S = s
5251
i := f(s.Int())
5352
_ = i
5453
}

internal/refactor/inline/inline.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -763,11 +763,15 @@ func (st *state) inlineCall() (*inlineCallResult, error) {
763763
n := len(params) - 1
764764
ordinary, extra := args[:n], args[n:]
765765
var elts []ast.Expr
766+
freevars := make(map[string]bool)
766767
pure, effects := true, false
767768
for _, arg := range extra {
768769
elts = append(elts, arg.expr)
769770
pure = pure && arg.pure
770771
effects = effects || arg.effects
772+
for k, v := range arg.freevars {
773+
freevars[k] = v
774+
}
771775
}
772776
args = append(ordinary, &argument{
773777
expr: &ast.CompositeLit{
@@ -779,7 +783,7 @@ func (st *state) inlineCall() (*inlineCallResult, error) {
779783
pure: pure,
780784
effects: effects,
781785
duplicable: false,
782-
freevars: nil, // not needed
786+
freevars: freevars,
783787
})
784788
}
785789
}
@@ -1453,9 +1457,26 @@ next:
14531457
// references among other arguments which have non-zero references
14541458
// within the callee.
14551459
if v, ok := caller.lookup(free).(*types.Var); ok && within(v.Pos(), caller.enclosingFunc.Body) && !isUsedOutsideCall(caller, v) {
1456-
logf("keeping param %q: arg contains perhaps the last reference to caller local %v @ %v",
1457-
param.info.Name, v, caller.Fset.PositionFor(v.Pos(), false))
1458-
continue next
1460+
1461+
// Check to see if the substituted var is used within other args
1462+
// whose corresponding params ARE used in the callee
1463+
usedElsewhere := func() bool {
1464+
for i, param := range params {
1465+
if i < len(args) && len(param.info.Refs) > 0 { // excludes original param
1466+
for name := range args[i].freevars {
1467+
if caller.lookup(name) == v {
1468+
return true
1469+
}
1470+
}
1471+
}
1472+
}
1473+
return false
1474+
}
1475+
if !usedElsewhere() {
1476+
logf("keeping param %q: arg contains perhaps the last reference to caller local %v @ %v",
1477+
param.info.Name, v, caller.Fset.PositionFor(v.Pos(), false))
1478+
continue next
1479+
}
14591480
}
14601481
}
14611482
}

internal/refactor/inline/inline_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,13 +731,25 @@ func TestSubstitution(t *testing.T) {
731731
`func _() { var local int; _ = local }`,
732732
},
733733
{
734-
"Arguments that are used are detected",
734+
"Arguments that are used by other arguments are detected",
735735
`func f(x, y int) { print(x) }`,
736736
`func _() { var z int; f(z, z) }`,
737+
`func _() { var z int; print(z) }`,
738+
},
739+
{
740+
"Arguments that are used by other variadic arguments are detected",
741+
`func f(x int, ys ...int) { print(ys) }`,
742+
`func _() { var z int; f(z, 1, 2, 3, z) }`,
743+
`func _() { var z int; print([]int{1, 2, 3, z}) }`,
744+
},
745+
{
746+
"Arguments that are used by other variadic arguments are detected, 2",
747+
`func f(x int, ys ...int) { print(ys) }`,
748+
`func _() { var z int; f(z) }`,
737749
`func _() {
738750
var z int
739751
var _ int = z
740-
print(z)
752+
print([]int{})
741753
}`,
742754
},
743755
{

0 commit comments

Comments
 (0)