Programming

Modernizing Go Code with Source-Level Inlining and go fix

2026-05-13 20:08:46

Introduction

Keeping Go codebases modern and efficient is a constant challenge. With Go 1.26, the newly redesigned go fix subcommand provides powerful tools to automate this process. A standout feature is the source-level inliner, which allows you to replace function calls with their implementation directly in your source files. This article explores how the source-level inliner works, its role in go fix, and how you can leverage it for seamless API migrations and refactoring.

Modernizing Go Code with Source-Level Inlining and go fix
Source: blog.golang.org

The Revamped go fix in Go 1.26

A Modern Approach to Code Updates

The go fix command has been completely reimplemented to help developers keep their code aligned with the latest language and library changes. While earlier versions offered simple, targetted fixes, the new go fix introduces a flexible framework that enables self-service modernizers. Package authors can now define their own migration rules without waiting for official updates. For a broader overview, see the introductory post on this blog (internal link placeholder).

Understanding Source-Level Inlining

What Is Source-Level Inlining?

Source-level inlining is a transformation that durably modifies your source code by replacing a function call with a copy of the function body, substituting actual arguments for parameters. For example, if you have a function sum called from six, inlining that call would expand the call site into the computation of the sum directly.

This is fundamentally different from compiler-level inlining, which operates on an internal representation and does not change the source files. Compiler inlining is ephemeral—it optimizes the generated object code but leaves your text untouched. Source-level inlining, on the other hand, rewrites the source, making it a refactoring tool rather than an optimization pass.

How It Differs from Compiler Inlining

The Go compiler has long performed inlining to improve performance, but that transformation is invisible to the developer. Source-level inlining is visible and permanent: after applying it, you can see the inlined code in your project. This distinction is crucial for code maintenance and readability. For instance, when a function used only once becomes simpler to understand inline, source-level inlining helps keep the codebase clean.

Practical Applications of the Source-Level Inliner

Integration with gopls

If you use gopls (the Go language server), you may have already encountered the source-level inliner without knowing it. The Inline call code action, available in VS Code under the "Source Action…" menu, relies on this technology. Additionally, refactorings like Change signature and Remove unused parameter use the inliner internally to handle subtle correctness issues when modifying function call sites.

Modernizing Go Code with Source-Level Inlining and go fix
Source: blog.golang.org

Self-Service API Migrations via go fix

The same source-level inliner powers one of the go fix analyzers. This allows any package author to define self-service API migrations. For example, if you deprecate a function and provide a new one, you can write a rule that automatically replaces all calls to the old function with the new implementation—all through inlining and substitution. This approach is safe and straightforward, reducing manual effort and ensuring consistency across large codebases.

The Technology Behind Source-Level Inlining

Handling Subtle Correctness Issues

Inlining a function call sounds simple, but it must respect Go's scoping, naming, and evaluation rules. The source-level inliner carefully handles:

These details make the inliner a robust building block for advanced refactoring tools. By using it, tools like gopls and go fix can apply transformations that would be error-prone if done manually.

Getting Started with Source-Level Inlining

To try source-level inlining with go fix, ensure you have Go 1.26 installed. Run go fix ./... in your module directory to apply all available modernizers. For custom migrations, package authors can define analyzers using the golang.org/x/tools/go/analysis package and integrate them with the go fix framework.

For interactive refactoring, use gopls’ Inline call action. This gives you a preview before committing the changes.

Source-level inlining is a powerful addition to the Go ecosystem, bridging the gap between compiler optimizations and developer-friendly refactoring. Whether you're migrating APIs or cleaning up code, this feature helps you keep your projects modern with less effort.

Explore

Critical Linux 'Copy Fail' Vulnerability Exposes Major Distros to Root Takeover 6 Critical Facts About TGR-STA-1030's Resurgent Threat in Latin America Preserving the American Dream: Urgent Action Against Economic Inequality and Civic Disengagement Secure Your AI Agents with AWS MCP Server: Q&A on the New General Availability How to Participate in the 2026 Rails Developer Community Survey and Shape the Future of Ruby on Rails