● LIVE   Breaking News & Analysis
Hrslive
2026-05-03
Programming

Go 1.26's Source-Level Inliner: A Self-Service Tool for API Migrations

Go 1.26 introduces a source-level inliner that enables self-service API migrations via 'go fix'. It replaces function calls with their bodies in source code, handling variable shadowing and order of evaluation.

Introduction

Go 1.26 brings a completely reworked go fix subcommand, designed to help developers keep their codebases modern and up to date. While earlier versions of go fix offered a few built-in transformations for new language features, the new implementation goes further by introducing a self-service approach: package authors can now define their own automatic migration rules. The key enabler behind this flexibility is the source-level inliner, a feature that also powers interactive refactorings in editors. In this article, we'll explore what the source-level inliner is, how it works, and why it matters for Go developers.

Go 1.26's Source-Level Inliner: A Self-Service Tool for API Migrations
Source: blog.golang.org

What Is Source-Level Inlining?

Inlining a function call means replacing the call site with a copy of the called function's body, substituting actual arguments for formal parameters. This is a familiar optimization performed by compilers (including Go's) on their internal representations to generate faster code. However, the source-level inliner does something different: it applies the same transformation durably to your source code, modifying .go files permanently.

If you've ever used the “Inline call” refactoring provided by gopls (Go's language server) you've already used the source-level inliner. In VS Code, this appears under the “Source Action…” menu. The transformation looks like this: before inlining, you might have a call like sum(a, b, c); after inlining, the call is replaced by the actual logic of the sum function.

Role in go fix

The new go fix includes several bespoke modernizers for language changes (e.g., for range integer loops) and library updates. But the source-level inliner is the first “self-service” analyzer: it allows any package author to express simple API migrations and updates in a straightforward and safe way. When you run go fix, it can invoke the inliner as one of its analyzers, applying user-defined rewriting rules automatically.

This means library maintainers can ship upgrade recipes that go fix can execute, reducing the manual effort required when an API changes. For example, if a function is deprecated and replaced by a new one, the inliner can be configured to replace all uses of the old function with the new one, potentially with adjusted arguments.

How the Source-Level Inliner Works

The inliner builds on an algorithm developed in 2023 specifically for Go. It must handle many subtle correctness issues that arise when refactoring function calls:

  • Variable shadowing: The inliner renames variables to avoid name clashes.
  • Return statements: It correctly transforms return statements inside the inlined body to return from the enclosing function.
  • Side effects: If the same expression appears multiple times in the inlined body, the inliner ensures side effects are evaluated exactly once by introducing temporary variables.
  • Order of evaluation: It preserves Go's evaluation order guarantees.

These complexities make source-level inlining significantly harder than the compiler's internal inlining, because the result must be valid, idiomatic Go source code that compiles correctly and behaves identically to the original.

Go 1.26's Source-Level Inliner: A Self-Service Tool for API Migrations
Source: blog.golang.org

A Building Block for Refactoring

Beyond go fix, the source-level inliner is a crucial component in other refactoring tools. For instance, gopls uses it for “Change signature” and “Remove unused parameter” refactorings. When you remove a parameter, the inliner can replace all calls to the original function with calls to the new signature, adjusting arguments accordingly. This shows how the inliner is not just a one-trick pony but a foundational tool that powers multiple transformations.

Self-Service API Migration

One of the most exciting aspects is the ability for package authors to create their own migration rules. The go fix command can be extended with analyzers that use the inliner. These analyzers can be distributed to users, who can then run go fix to automatically update their codebases when a library introduces breaking changes or migrations. This reduces the burden on both library authors (who no longer need to write manual upgrade scripts) and users (who get reliable, automatic updates).

The current implementation focuses on simple inlining—replacing a call with the body of the called function—but this already covers many common migration patterns. For example, renaming a function and updating all its call sites can be achieved by an inline that substitutes the old name with the new body (which may call the new name). More complex transformations are possible by combining inlining with other analyzers.

Conclusion

The source-level inliner is a powerful new tool in Go 1.26's go fix ecosystem. It provides a safe, durable way to transform source code, supporting both interactive refactoring and automated migration. By empowering package authors to define their own modernizers, it paves the way for a more automated and less error-prone upgrade experience for the entire Go community. Whether you're a library maintainer or an everyday Go developer, the source-level inliner is a feature worth understanding—and using.

For more details, see the official Go blog post //go:fix inline and the source-level inliner by Alan Donovan.