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.
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:
Because fmt.Println's arguments are each converted to
any
, the implicit conversion fromdiscard
toio.Writer
is not significant within the body ofg
and could be omitted. By contrast, werefmt.Println
replaced bypanic
, the conversion would not be safe to remove, because in generalpanic(x)
is not equivalent topanic(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