Skip to content

Commit 64bfecc

Browse files
committed
gopls/internal/golang: fix extract bug with anon functions
When the extracted block contains return statements but doesn't have any non-nested returns, we adjust all return statements in the extracted function. However, we need to avoid modifying the return statements of anonymous functions since this would change function behavior or cause a type error. Fixes golang/go#73972 Change-Id: I6e5c145c844d29c9ceae32da341b99a1ff1b2d54 Reviewed-on: https://go-review.googlesource.com/c/tools/+/678915 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent 4546fbd commit 64bfecc

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

gopls/internal/golang/extract.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,6 +1896,10 @@ func adjustReturnStatements(returnTypes []*ast.Field, seenVars map[types.Object]
18961896
if n == nil {
18971897
return false
18981898
}
1899+
// Don't modify return statements inside anonymous functions.
1900+
if _, ok := n.(*ast.FuncLit); ok {
1901+
return false
1902+
}
18991903
if n, ok := n.(*ast.ReturnStmt); ok {
19001904
n.Results = slices.Concat(zeroVals, n.Results)
19011905
return false
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
This test verifies the fix for golang/go#73972: extraction should
2+
not modify the return statements of anonymous functions.
3+
4+
-- go.mod --
5+
module mod.test/extract
6+
7+
go 1.18
8+
9+
-- a.go --
10+
package extract
11+
12+
import (
13+
"fmt"
14+
"strings"
15+
)
16+
17+
func main() {
18+
b := strings.ContainsFunc("a", func(_ rune) bool { //@codeaction("b", "refactor.extract.function", end=end, result=ext)
19+
return false
20+
})
21+
if b {
22+
return
23+
} //@loc(end, "}")
24+
fmt.Println(b)
25+
}
26+
27+
-- @ext/a.go --
28+
package extract
29+
30+
import (
31+
"fmt"
32+
"strings"
33+
)
34+
35+
func main() {
36+
b, shouldReturn := newFunction()
37+
if shouldReturn {
38+
return
39+
} //@loc(end, "}")
40+
fmt.Println(b)
41+
}
42+
43+
func newFunction() (bool, bool) {
44+
b := strings.ContainsFunc("a", func(_ rune) bool { //@codeaction("b", "refactor.extract.function", end=end, result=ext)
45+
return false
46+
})
47+
if b {
48+
return false, true
49+
}
50+
return b, false
51+
}
52+

0 commit comments

Comments
 (0)