Learn

//go:fix inline is an API migration tool

Go’s source-level inliner is not about speed — it is a safe way to rewrite call sites when you deprecate an API.

//go:fix inline is an API migration tool

Compiler inlining optimizes for runtime. Source-level inlining optimizes for tidiness: replace a call with the callee body so old APIs can die without a fleet of one-off rewrite scripts.

The useful mental model

  1. You deprecate oldpkg.Foo by implementing it as a thin forwarder to newpkg.Foo.
  2. You add //go:fix inline on the old function.
  3. go fix (or gopls) rewrites call sites to the inlined body — ideally just the new call.

That is self-service migration: library authors encode the rewrite; consumers apply a stock tool.

Why it is harder than it looks

A naive “paste the body” pass breaks programs. Arguments have side effects. Parameters appear more than once. Constants that were fine at runtime become illegal at compile time (""[0]). Names shadow. defer changes lifetime. The inliner is a small compiler whose goal is correctness first, neatness second.

What changes in practice

  • Prefer forwarding + //go:fix inline over “please rewrite your imports by hand.”
  • Expect conservative output sometimes — review the diff; tidy if the binding vars are noisy.
  • Treat this as the same class of tool as Java/Kotlin/C++ monorepo migrators, not as a micro-optimization tip.

Signal from the Go Blog write-up on the 1.26 source-level inliner: go.dev/blog/inliner.