Codenil

Modernizing Go Code with the Source-Level Inliner in Go 1.26

Published: 2026-05-06 12:28:59 | Category: Programming

Go 1.26 introduces a completely reimagined go fix subcommand, designed to help developers keep their codebases modern and maintainable with minimal effort. Among its standout features is the source-level inliner, a tool that enables package authors to define simple, safe, and automated API migrations and code updates. In this article, we’ll explore what the source-level inliner is, how it works, and how you can leverage it in your own projects.

What Is Source-Level Inlining?

Source-level inlining is the process of replacing a function call with a copy of the called function’s body, substituting actual arguments for the parameters. Unlike compiler inlining—which performs a similar transformation on an ephemeral internal representation to generate faster machine code—source-level inlining modifies the source code itself, producing a durable, human-readable result.

Modernizing Go Code with the Source-Level Inliner in Go 1.26
Source: blog.golang.org

If you’ve ever used the “Inline call” refactoring in gopls (available in VS Code under the “Source Action…” menu), you’ve already experienced source-level inlining. For example, consider a function six that calls a helper sum:

func six() int {
    return sum(1, 2, 3)
}

func sum(a, b, c int) int {
    return a + b + c
}
func six() int {
    return 1 + 2 + 3
}

The inliner replaces the call to sum with its body, inline, making the code more explicit and often simpler to optimize by hand or by the compiler.

The Role in go fix

Go 1.26’s go fix command includes several “modernizers” that automatically update code to use new language features or library APIs. The source-level inliner is a foundational tool that powers many of these modernizers. More importantly, it opens the door to self-service API migration: any package author can now write their own migration rules using the same underlying mechanism.

Self-Service API Migration

Package maintainers often need to deprecate old APIs and guide users toward new ones. With the source-level inliner, they can define a “fix” that automatically replaces calls to deprecated functions with equivalent code using the new API. This is done by labeling the old function with a special directive, such as //go:fix inline, and providing a replacement body. When users run go fix, all calls to the deprecated function are inlined and then replaced with the desired modern code.

This approach is safe and predictable because the inliner handles many subtle edge cases—such as variable scoping, side effects, and return values—that manual replacements might miss. It’s a huge step toward reducing the friction of upgrading dependencies and language versions.

Modernizing Go Code with the Source-Level Inliner in Go 1.26
Source: blog.golang.org

Integration with Refactoring Tools

Beyond go fix, the source-level inliner is a key building block for gopls refactorings like “Change Signature” and “Remove Unused Parameter.” These operations need to update all call sites of a function, and the inliner provides a reliable way to propagate those changes through complex expression trees. The result is a tool that can safely perform large-scale refactorings without breaking code.

Technical Highlights

The source-level inliner is not merely a text substitution; it operates on Go’s abstract syntax tree (AST), preserving semantic correctness. It handles:

  • Argument evaluation order: It ensures that arguments are evaluated exactly once, in the correct order, even when inlining into complex expressions.
  • Variable name conflicts: It renames variables to avoid shadowing or colliding with existing names in the calling scope.
  • Control flow constructs: It correctly inlines functions containing return, if, for, and other statements while preserving the original behavior.

These capabilities make it suitable not only for automated migration but also for interactive use in IDEs, where developers expect instant, reliable transformations.

Looking Ahead

The source-level inliner is part of a broader effort to make Go tooling more proactive and helpful. By combining it with the go fix framework, the Go team has created a platform that can evolve with the language. Package authors are encouraged to experiment with //go:fix inline directives and provide feedback, as this self-service model could become a standard way to manage API deprecations and migrations across the Go ecosystem.

To learn more, see the original Go blog post and the Go 1.26 release notes.