internal/refactor/inline: work around channel type misformatting
This change adds parens around the type in T(x) conversions
where T is a receive-only channel type, as previously it
would be misformatted as a receive of a receive.
Updates golang/go#63362
Change-Id: I935b5598d4bc3ea57dd52964e8b02005f5e6ef72
Reviewed-on: https://go-review.googlesource.com/c/tools/+/532576
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/refactor/inline/falcon.go b/internal/refactor/inline/falcon.go
index 9ad57d7..9863e8d 100644
--- a/internal/refactor/inline/falcon.go
+++ b/internal/refactor/inline/falcon.go
@@ -610,10 +610,7 @@
// Possible "value out of range".
kX := st.expr(e.Args[0])
if kX != nil && isBasic(tv.Type, types.IsConstType) {
- conv := &ast.CallExpr{
- Fun: makeIdent(st.typename(tv.Type)),
- Args: []ast.Expr{st.toExpr(kX)},
- }
+ conv := convert(makeIdent(st.typename(tv.Type)), st.toExpr(kX))
if is[ast.Expr](kX) {
st.emit(conv)
}
diff --git a/internal/refactor/inline/inline.go b/internal/refactor/inline/inline.go
index 08a4594..f3bc4db 100644
--- a/internal/refactor/inline/inline.go
+++ b/internal/refactor/inline/inline.go
@@ -1284,10 +1284,7 @@
// a binding decl or when using the literalization
// strategy.
if len(param.info.Refs) > 0 && !trivialConversion(args[i].typ, params[i].obj) {
- arg.expr = &ast.CallExpr{
- Fun: params[i].fieldType, // formatter adds parens as needed
- Args: []ast.Expr{arg.expr},
- }
+ arg.expr = convert(params[i].fieldType, arg.expr)
logf("param %q: adding explicit %s -> %s conversion around argument",
param.info.Name, args[i].typ, params[i].obj.Type())
}
diff --git a/internal/refactor/inline/inline_test.go b/internal/refactor/inline/inline_test.go
index 58abc1e..8918977 100644
--- a/internal/refactor/inline/inline_test.go
+++ b/internal/refactor/inline/inline_test.go
@@ -382,6 +382,12 @@
print(s, s, 0, 0)
}`,
},
+ {
+ "Workaround for T(x) misformatting (#63362).",
+ `func f(ch <-chan int) { <-ch }`,
+ `func _(ch chan int) { f(ch) }`,
+ `func _(ch chan int) { <-(<-chan int)(ch) }`,
+ },
})
}
diff --git a/internal/refactor/inline/util.go b/internal/refactor/inline/util.go
index 6d8d3fa..98d654e 100644
--- a/internal/refactor/inline/util.go
+++ b/internal/refactor/inline/util.go
@@ -103,3 +103,17 @@
}
return false
}
+
+// convert returns syntax for the conversion T(x).
+func convert(T, x ast.Expr) *ast.CallExpr {
+ // The formatter generally adds parens as needed,
+ // but before go1.22 it had a bug (#63362) for
+ // channel types that requires this workaround.
+ if ch, ok := T.(*ast.ChanType); ok && ch.Dir == ast.RECV {
+ T = &ast.ParenExpr{X: T}
+ }
+ return &ast.CallExpr{
+ Fun: T,
+ Args: []ast.Expr{x},
+ }
+}