Description
This contrived example demonstrates that the source-level inliner (activated through gopls' refactor.inline code action) adds conversions to interface types even when they are not necessary:
func f(d discard) {
g(d) // inlining this => fmt.Println(io.Writer(d)), where fmt.Println(d) would do
}
func g(w io.Writer) { fmt.Println(w) }
var d discard
type discard struct{}
func (discard) Write(p []byte) (int, error) { return len(p), nil }
Because fmt.Println's arguments are each converted to any
, the implicit conversion from discard
to io.Writer
is not significant within the body of g
and could be omitted. By contrast, were fmt.Println
replaced by panic
, the conversion would not be safe to remove, because in general panic(x)
is not equivalent to panic(any(x))
.
The inliner should detect, for each interface-typed parameter of the callee, whether all its uses in the callee's body are converted explicitly or implicitly to an interface type, so that the caller-side interface conversion may be safely omitted.
Googlers: see internal issue b/354664998