---
title: "Go Fix: A Revolução na Modernização de Código com Inlining Inteligente"
url: "https://golang.com.br/blog/go-fix-a-revolucao-na-modernizacao-de-codigo-com-inlining-inteligente/"
markdown_url: "https://golang.com.br/blog/go-fix-a-revolucao-na-modernizacao-de-codigo-com-inlining-inteligente.MD"
description: "O Go 1.26 introduziu uma nova implementação do comando `go fix`, projetada para auxiliar na atualização e modernização do código Go. Uma das..."
date: "2026-03-10"
author: "Go Blog (Resumo)"
---

# Go Fix: A Revolução na Modernização de Código com Inlining Inteligente

O Go 1.26 introduziu uma nova implementação do comando `go fix`, projetada para auxiliar na atualização e modernização do código Go. Uma das...


O Go 1.26 introduziu uma nova implementação do comando `go fix`, projetada para auxiliar na atualização e modernização do código Go. Uma das funcionalidades mais notáveis é o "source-level inliner", que permite a autores de pacotes expressarem migrações e atualizações de API de forma simples e segura. Este resumo detalha o funcionamento do inliner, seus casos de uso e a tecnologia por trás dele.

### O Que é Source-Level Inlining?

O inlining, em geral, é uma técnica de otimização de compiladores que substitui uma chamada de função pelo corpo da função chamada, substituindo os argumentos pelos parâmetros. O "source-level inlining" faz isso diretamente no código fonte, modificando-o de forma duradoura. Isso difere do inlining tradicional feito pelo compilador, que opera em representações intermediárias e é descartado após a compilação.

Se você já usou o recurso "Inline call" do `gopls` (o servidor de linguagem Go), você já utilizou o source-level inliner. Ele está disponível em editores como VS Code, através do menu "Source Action...".  O inliner é uma ferramenta fundamental para outras refatorações, como "Change signature" e "Remove unused parameter", pois lida com sutilezas que surgem ao refatorar chamadas de função.

A grande novidade é que este mesmo inliner agora faz parte do `go fix`, permitindo migrações e upgrades de API "self-service" através do uso de comentários com a diretiva `//go:fix inline`.

### Exemplos Práticos de Uso

#### Renomeando `ioutil.ReadFile`

Em Go 1.16, a função `ioutil.ReadFile` foi depreciada em favor de `os.ReadFile`.  Embora a promessa de compatibilidade do Go impeça a remoção da função antiga, o inliner permite que os usuários migrem para a nova função.

Primeiro, a função antiga é anotada com `//go:fix inline`:

```go
package ioutil

import "os"

// ReadFile reads the file named by filename…
// Deprecated: As of Go 1.16, this function simply calls [os.ReadFile].
//go:fix inline
func ReadFile(filename string) ([]byte, error) {
    return os.ReadFile(filename)
}
```

Ao executar `go fix` em um arquivo que contenha chamadas a `ioutil.ReadFile`, o comando substituirá a chamada pela equivalente em `os.ReadFile`:

```
$ go fix -diff ./...
-import "io/ioutil"
+import "os"

-   data, err := ioutil.ReadFile("hello.txt")
+   data, err := os.ReadFile("hello.txt")
```

A principal vantagem é que a transformação preserva o comportamento do programa (exceto em casos de introspecção da pilha de chamadas). Isso o torna mais seguro do que ferramentas de reescrita arbitrária como `gofmt -r`.

Grandes empresas como o Google utilizam ferramentas semelhantes para eliminar milhões de chamadas a funções depreciadas em bases de código massivas. O inliner do Go já foi utilizado para preparar milhares de *changelists* internos.

#### Corrigindo Falhas de Design de API

O inliner também pode ser usado para corrigir falhas de design em APIs. Considere o seguinte pacote hipotético `oldmath`:

```go
// Package oldmath is the bad old math package.
package oldmath

// Sub returns x - y.
func Sub(y, x int) int

// Inf returns positive infinity.
func Inf() float64

// Neg returns -x.
func Neg(x int) int
```

Este pacote tem vários problemas: a ordem dos parâmetros em `Sub` está invertida, `Inf` implicitamente prefere um dos infinitos, e `Neg` é redundante.  Para migrar os usuários para um novo pacote `newmath` que corrige esses problemas, o primeiro passo é implementar a API antiga em termos da nova e depreciar as funções antigas. Em seguida, adicionam-se as diretivas `//go:fix inline`:

```go
// Package oldmath is the bad old math package.
package oldmath

import "newmath"

// Sub returns x - y.
// Deprecated: the parameter order is confusing.
//go:fix inline
func Sub(y, x int) int {
    return newmath.Sub(x, y)
}

// Inf returns positive infinity.
// Deprecated: there are two infinite values; be explicit.
//go:fix inline
func Inf() float64 {
    return newmath.Inf(+1)
}

// Neg returns -x.
// Deprecated: this function is unnecessary.
//go:fix inline
func Neg(x int) int {
    return newmath.Sub(0, x)
}
```

Agora, ao executar `go fix`, as chamadas às funções antigas serão substituídas pelas novas:

```go
import "oldmath"

var nine = oldmath.Sub(1, 10) // diagnostic: "call to oldmath.Sub should be inlined"
```

será transformado em:

```go
import "newmath"

var nine = newmath.Sub(10, 1)
```

Note que a ordem dos argumentos em `Sub` foi corrigida.

O inliner também funciona com tipos e constantes. Por exemplo:

```go
package oldmath

//go:fix inline
type Rational = newmath.Rational

//go:fix inline
const Pi = newmath.Pi
```

### Desafios e Considerações Técnicas

O inlining de código fonte não é uma tarefa trivial e apresenta vários desafios:

*   **Escopo de Variáveis:**  O inliner deve garantir que as variáveis introduzidas pelo corpo da função inlinada não colidam com variáveis existentes no escopo da chamada. A solução envolve renomear variáveis, se necessário, para evitar conflitos.
*   **Retornos Múltiplos:** Funções com múltiplos retornos exigem cuidado para garantir que todos os valores de retorno sejam corretamente atribuídos após o inlining.
*   **`defer` statements:** Quando uma função contem `defer` statements, o inlining deve garantir que estes statements sejam executados no momento correto.
*   **`go` statements (goroutines):** Inlining de funções que iniciam goroutines pode ser problematico e requer tratamento especial.
*   **`recover`:** A semântica do `recover` pode ser afetada pelo inlining, e o inliner precisa estar ciente destas nuances.
*   **`goto` statements:**  `goto` statements podem tornar o inlining complexo, especialmente se o alvo do `goto` estiver fora da função inlinada.
*   **`break` e `continue` em loops:**  O inliner deve garantir que os statements `break` e `continue` continuem a funcionar corretamente após o inlining, o que pode exigir ajustes na estrutura do código.
*   **`return` statements:** O inliner deve garantir que os `return` statements na função inlinada retornem corretamente do contexto da chamada. Isso pode envolver a introdução de novos `return` statements ou a modificação dos existentes.

O artigo original não entra em detalhes sobre como cada um desses casos é tratado, mas implica que o inliner do Go possui mecanismos para lidar com essas complexidades de forma robusta.

### Implementação e Algoritmo

O inliner do Go é implementado usando a biblioteca `golang.org/x/tools/go/analysis`. Ele opera em duas fases:

1.  **Análise:**  A primeira fase analisa o código fonte para identificar chamadas de função que podem ser inlinadas. Ele também verifica se a função chamada está marcada com a diretiva `//go:fix inline`.
2.  **Transformação:**  A segunda fase realiza a transformação do código, substituindo a chamada de função pelo corpo da função. Esta fase lida com os desafios mencionados acima, como escopo de variáveis, retornos múltiplos e `defer` statements.

O algoritmo é projetado para ser seguro e preservar o comportamento do programa. Ele evita transformações que possam introduzir erros ou alterar a semântica do código.

### Implicações Práticas e Benefícios

O source-level inliner do Go oferece vários benefícios:

*   **Modernização de Código:**  Facilita a migração de APIs antigas para novas, permitindo que os desenvolvedores atualizem seu código de forma incremental e segura.
*   **Correção de Falhas de Design:**  Permite corrigir falhas de design em APIs, como a ordem incorreta de parâmetros ou a falta de clareza em constantes.
*   **Automatização de Refatorações:**  Automatiza tarefas de refatoração que seriam tediosas e propensas a erros se feitas manualmente.
*   **Melhora na Manutenibilidade:**  Simplifica o código, eliminando a necessidade de manter APIs antigas e corrigindo falhas de design.
*   **Redução de Dependências:**  Pode permitir a remoção de dependências, uma vez que as chamadas a funções de um pacote podem ser inlineadas, eliminando a necessidade do pacote original.

### Conclusão

O source-level inliner é uma adição poderosa ao ecossistema Go, oferecendo uma maneira segura e automatizada de modernizar o código, corrigir falhas de design e simplificar a manutenção. A combinação da diretiva `//go:fix inline` com o comando `go fix` permite que os autores de pacotes forneçam migrações de API "self-service", reduzindo o esforço necessário para manter o código atualizado e em conformidade com as melhores práticas. Apesar dos desafios técnicos envolvidos, o inliner do Go parece lidar com as complexidades do código Go de forma robusta, oferecendo uma ferramenta valiosa para os desenvolvedores Go.

---

## Artigo Original

Este e um resumo em português do artigo original publicado no blog oficial do Go.

**Titulo original:** //go:fix inline and the source-level inliner

[Leia o artigo completo em ingles no Go Blog](https://go.dev/blog/inliner)

*Autor original: Alan Donovan*
