---
title: "cargo-hack: Features e Powerset na CI Rust | Rust Brasil"
url: "https://rustlang.com.br/blog/cargo-hack-features-powerset-ci-rust-2026/"
markdown_url: "https://rustlang.com.br/blog/cargo-hack-features-powerset-ci-rust-2026.MD"
description: "Use cargo-hack para testar features, --each-feature e --feature-powerset em Rust. Guia com workspaces, CI, MSRV, nextest, exclusões e armadilhas comuns."
date: "2026-08-11"
author: "Equipe Rust Brasil"
---

# cargo-hack: Features e Powerset na CI Rust | Rust Brasil

Use cargo-hack para testar features, --each-feature e --feature-powerset em Rust. Guia com workspaces, CI, MSRV, nextest, exclusões e armadilhas comuns.


**O `cargo-hack` é a ferramenta certa quando um crate Rust tem várias features opcionais e você precisa garantir que elas compilam e testam de verdade — sozinhas, juntas e sem o conjunto mágico que só passa no notebook do mantenedor.** Instale com `cargo install cargo-hack --locked`, rode `cargo hack check --each-feature` na raiz do projeto e trate o resultado como o primeiro filtro de regressão de feature flags. Em bibliotecas, workspaces e crates publicados, isso costuma pegar mais bugs do que mais um `cargo test` com `--all-features`.

Este guia mostra o que o `cargo-hack` resolve, quando usar `--each-feature` ou `--feature-powerset`, como montar CI barata e útil, como combinar a ferramenta com [cargo-nextest](/blog/cargo-nextest-testes-rust-2026/), [cargo-msrv](/blog/cargo-msrv-versao-minima-rust-ci-2026/) e workspaces, e quais armadilhas geram falsos verdes ou builds eternamente caros.

## Resposta rápida: o fluxo recomendado

| Etapa | Comando ou configuração | Objetivo |
|---|---|---|
| Instalar | `cargo install cargo-hack --locked` | Disponibilizar o subcomando |
| Checagem diária | `cargo hack check --each-feature` | Validar features isoladas |
| Testes | `cargo hack test --each-feature` | Exercitar a matriz no runtime |
| Powerset seletivo | `cargo hack check --feature-powerset --depth 2` | Combinar poucas features |
| Workspace | `cargo hack check --workspace --each-feature` | Cobrir vários pacotes |
| CI enxuta | `check` no PR, `test`/powerset no nightly | Controlar custo |

Antes de copiar flags para um pipeline crítico, confira `cargo hack --help` e o help do subcomando. A ferramenta evolui; fixar a versão na CI evita surpresas quando a sintaxe ou o comportamento padrão mudam.

## Por que features Rust quebram sem ninguém perceber

Features do Cargo são poderosas e traiçoeiras. Elas permitem:

- backends opcionais de TLS, banco ou runtime;
- integrações com crates pesados sem inflar o default;
- APIs experimentais atrás de flags;
- builds enxutos para embedded, WASM ou CLI.

O problema é que a maioria dos times desenvolve com um conjunto fixo de features — normalmente as defaults do dia a dia ou `--all-features` no atalho local. Isso esconde regressões clássicas:

1. uma feature opcional deixa de compilar sozinha;
2. duas features juntas conflitam em tipos, features transitivas ou `cfg`;
3. o default passa, mas `--no-default-features` quebra o consumidor minimalista;
4. um exemplo, teste ou binário auxiliar só existe atrás de uma feature e nunca roda na CI;
5. a feature A ativa uma dependência que eleva a [MSRV](/blog/cargo-msrv-versao-minima-rust-ci-2026/) sem aviso;
6. o workspace compila o pacote app, mas a lib publicada fica inconsistente.

`--all-features` não resolve tudo. Em projetos com backends mutuamente exclusivos, ligar todas as features ao mesmo tempo pode ser uma configuração inválida. Em outros casos, `--all-features` mascara exatamente o bug de “feature sozinha não compila”.

O `cargo-hack` existe para transformar essa matriz informal em um comando repetível.

## O que é cargo-hack

O [`cargo-hack`](https://github.com/taiki-e/cargo-hack) é um subcomando do Cargo focado em executar o mesmo comando Cargo — `check`, `test`, `clippy`, `build` e afins — sob várias configurações. Em vez de escrever um shell script com loops de features, você declara a política:

- cada feature isolada;
- powerset completo ou limitado por profundidade;
- exclusões e inclusões;
- pacotes de um workspace;
- toolchains diferentes.

Na prática, a ferramenta responde a perguntas de mantenedor:

1. o crate compila sem features extras?
2. cada feature opcional ainda compila sozinha?
3. combinações importantes continuam válidas?
4. o workspace inteiro respeita a mesma política?
5. a matriz ainda passa na toolchain que a biblioteca promete suportar?

Ela não substitui bom desenho de features. Se o grafo de flags for caótico, o `cargo-hack` só vai revelar o caos mais cedo — o que já é uma vitória.

## Instalando e primeiros comandos

```bash
cargo install cargo-hack --locked
cargo hack --version
```

Na raiz de um crate ou workspace:

```bash
# compila a base + cada feature opcional isolada
cargo hack check --each-feature

# equivalente em modo teste
cargo hack test --each-feature

# também valida o build sem default features
cargo hack check --each-feature --no-dev-deps
```

O padrão mental é simples:

1. escolha o **comando base** (`check`, `test`, `clippy`);
2. escolha a **matriz** (`--each-feature`, `--feature-powerset`, pacotes, toolchain);
3. restrinja o que for caro ou inválido;
4. automatize na CI o recorte que o time aguenta pagar em minutos.

Para inspeção rápida de regressão de API/compilação, prefira `check`. Para lógica condicional com `cfg(feature = ...)`, você precisa de `test` em algum ponto da esteira.

## `--each-feature` versus `--feature-powerset`

Essas duas flags são o coração do `cargo-hack`. Escolher errado é o jeito mais comum de transformar uma boa ideia em CI de 40 minutos.

### `--each-feature`

Testa, em linhas gerais:

- a configuração base;
- cada feature opcional isoladamente, em cima dessa base.

O custo cresce de forma aproximadamente linear com o número de features. É o padrão saudável para a maioria das bibliotecas e para pull requests.

```bash
cargo hack check --each-feature
cargo hack test --each-feature
```

Use quando:

- há muitas features e o powerset seria explosivo;
- a maior parte das flags é independente;
- você quer um sinal barato e frequente.

### `--feature-powerset`

Testa combinações entre features. Sem limites, o crescimento é exponencial: 8 features opcionais já podem gerar dezenas ou centenas de combinações, dependendo de defaults e filtros.

```bash
cargo hack check --feature-powerset
cargo hack check --feature-powerset --depth 2
```

Use quando:

- features interagem de verdade (`serde` + `async`, `json` + `yaml`, `rt-tokio` + `macros`);
- o número de flags relevantes é pequeno;
- o job pode ser mais lento (nightly, pré-release, cron).

### Uma regra prática

| Situação | Matriz recomendada |
|---|---|
| App interno com 1–2 features | `cargo test` normal ou `--all-features` |
| Lib com várias flags independentes | `--each-feature` no PR |
| Lib com 3–5 flags que interagem | `--feature-powerset --depth 2` |
| Backends mutuamente exclusivos | matriz explícita, não powerset cego |
| Workspace grande | `--each-feature` por pacote publicado |

Se a CI ficou lenta demais, o problema raramente é o `cargo-hack` em si: é a ausência de `--depth`, de exclusões e de separação entre job barato e job completo.

## Features mutuamente exclusivas e configurações inválidas

Nem toda combinação deve ser testada. Exemplos clássicos:

- `native-tls` versus `rustls`;
- `runtime-tokio` versus `runtime-async-std`;
- `postgres` versus `mysql` em um conector;
- features experimentais que não compõem com a API estável.

Nesses casos, um powerset ingênuo produz falhas “esperadas” e ensina o time a ignorar a CI. Em vez disso, modele a matriz:

```bash
# exemplo conceitual: valide cada backend de TLS isolado
cargo hack check --feature-powerset --depth 1 \
  --include-features native-tls,rustls
```

Ou documente jobs separados:

```text
job default ........ cargo test
job tls-native ..... cargo test --no-default-features --features native-tls
job tls-rustls ..... cargo test --no-default-features --features rustls
job each-feature ... cargo hack check --each-feature
```

O objetivo não é “rodar o máximo de combinações possíveis”. É **rodar as combinações que um consumidor real pode escolher**.

Se o `Cargo.toml` já expressa exclusão por documentação ou por erros de compilação propositais, deixe isso explícito no README e na CI. Surpresa é pior do que restrição.

## Workspaces, pacotes publicados e `--workspace`

Em monorepos, o erro clássico é testar só o binário da aplicação e publicar uma lib interna inconsistente. O `cargo-hack` ajuda a alinhar a política:

```bash
cargo hack check --workspace --each-feature
cargo hack test -p minha-lib --each-feature
```

Boas práticas de workspace:

1. **Separe pacotes publicados de ferramentas internas.** Nem todo crate do monorepo precisa da mesma matriz.
2. **Foque a matriz cara nos crates da API pública.** Apps e crates de integração podem usar um subconjunto.
3. **Evite features “fantasma” só para acomodar o workspace.** Se a feature existe, alguém vai ativá-la.
4. **Combine com a organização de workspaces.** O guia de [Cargo workspaces e monorepos](/blog/cargo-workspaces-monorepos-rust-2026/) cobre a estrutura; o `cargo-hack` cobre a verificação da matriz.

Em repositórios com dezenas de crates, comece por:

```bash
cargo hack check --workspace --each-feature --exclude crate-lento,crate-experimental
```

Depois reintroduza os excluídos em jobs dedicados.

## Montando CI útil sem quebrar o orçamento

Uma esteira saudável costuma ter camadas:

### Camada 1 — PR rápido

```bash
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo hack check --each-feature
cargo nextest run
```

Aqui o `cargo-hack` usa `check` para baratear. O [cargo-nextest](/blog/cargo-nextest-testes-rust-2026/) cobre os testes da configuração principal com melhor paralelismo.

### Camada 2 — PR completo ou merge queue

```bash
cargo hack test --each-feature
```

Suba para `test` quando houver lógica condicional relevante ou histórico de regressão em features.

### Camada 3 — nightly / pré-release

```bash
cargo hack check --feature-powerset --depth 2
cargo hack test --feature-powerset --depth 2 --exclude-features unstable
```

É o lugar certo para powerset, toolchains extras e combinações caras.

### Camada 4 — release

Antes de publicar no crates.io:

1. rode a matriz que define o contrato da crate;
2. verifique MSRV com [cargo-msrv](/blog/cargo-msrv-versao-minima-rust-ci-2026/);
3. rode [cargo-semver-checks](/blog/cargo-semver-checks-rust-api-ci-2026/) se a API pública importar;
4. limpe dependências mortas com [cargo-machete / cargo-udeps](/blog/cargo-machete-cargo-udeps-dependencias-nao-usadas-2026/);
5. revise supply chain com [cargo-deny e SBOM](/blog/rust-seguranca-supply-chain-cargo-deny-sbom-2026/).

O `cargo-hack` não é a única ferramenta da release, mas é a que responde: “as flags que documentamos ainda formam um produto coerente?”

## Combinando cargo-hack com nextest, clippy e MSRV

### nextest

```bash
cargo hack nextest run --each-feature
```

Confirme na versão instalada se o subcomando e os argumentos encaminhados estão como você espera. O ganho é rodar a matriz de features com o runner moderno de testes, em vez de reescrever a orquestração.

### clippy

```bash
cargo hack clippy --each-feature -- -D warnings
```

Útil para bibliotecas em que uma feature opcional introduz padrões que o Clippy só enxerga com aquele `cfg`. Em PRs, isso pode ser caro; em muitos times fica no nightly.

### MSRV e toolchains

O `cargo-hack` também ajuda a exercitar a mesma matriz em toolchains distintas. A divisão de responsabilidades fica clara:

| Ferramenta | Pergunta |
|---|---|
| `cargo-msrv` | Qual é a versão mínima que ainda compila o contrato? |
| `cargo-hack` | As combinações de features/pacotes continuam válidas? |
| `cargo test` / `nextest` | O comportamento está correto em uma configuração? |

Não use uma para fazer o trabalho da outra. Descobrir MSRV com powerset completo em toda PR é desperdiçar minutos de runner.

## Armadilhas comuns

### 1. Tratar `--all-features` como prova suficiente

`--all-features` valida uma superposição. Não prova que cada feature funciona sozinha nem que o consumidor sem defaults consegue compilar.

### 2. Powerset sem `--depth` em crate “só um pouco complexa”

A complexidade explode rápido. Se o job passou de orçamento, limite profundidade, exclua features instáveis e separe backends exclusivos.

### 3. Features só de dev misturadas na matriz pública

Flags usadas apenas para testes internos, mocks ou benchmarks não deveriam definir o contrato do usuário final. Mantenha a matriz pública legível.

### 4. Exemplos e bins esquecidos

Uma feature pode compilar a lib e quebrar um exemplo. Quando exemplos fazem parte do produto, inclua targets relevantes na política de CI.

### 5. Falso verde por cache mal compreendido

Caches de CI aceleram, mas uma chave que ignora a matriz de features pode reutilizar artefatos no momento errado. Inclua features, target e toolchain na chave, ou aceite rebuilds mais honestos.

### 6. Documentação desencontrada do `Cargo.toml`

Se o README promete “ative `serde` e `tls`”, a CI precisa conhecer essa combinação. Documentação sem matriz é marketing; matriz sem documentação é surpresa.

### 7. Ignorar impacto em tempo de build e tamanho

Features opcionais podem puxar dependências enormes. Depois de estabilizar a matriz, use [cargo-bloat](/blog/cargo-bloat-reduzir-tamanho-binario-rust-2026/) e [cargo-llvm-lines](/blog/cargo-llvm-lines-monomorfizacao-rust-2026/) para entender o custo de cada caminho de build — especialmente em CLI, WASM e embedded.

## Checklist para adotar cargo-hack

1. Liste as features do `Cargo.toml` e classifique: default, opcional isolada, interdependente, mutuamente exclusiva, experimental.
2. Escreva em uma frase o contrato de cada feature para o consumidor.
3. Adote `cargo hack check --each-feature` localmente.
4. Coloque a checagem barata no PR.
5. Decida se alguma combinação exige powerset limitado.
6. Exclua explicitamente combinações inválidas.
7. Separe jobs de app, lib publicada e crates internos no workspace.
8. Ligue a matriz de release a MSRV, semver e supply chain.
9. Meça o tempo de CI antes e depois; ajuste `--depth` e exclusões com dados.
10. Atualize README/changelog quando a política de features mudar.

## cargo-hack e carreira Rust

Em [vagas](/vagas/) e entrevistas de backend, sistemas e plataforma, feature flags bem desenhadas são sinal de maturidade. Saber explicar:

- por que `--all-features` não basta;
- como montar uma matriz barata de PR;
- como evitar backends exclusivos no mesmo powerset;
- como a política de features interage com MSRV e semver;

diferencia quem só “usa Cargo” de quem mantém biblioteca ou monorepo de verdade. Se você publica crates, contribui com open source ou lidera a esteira de um time Rust no Brasil, `cargo-hack` é uma das ferramentas que mais devolvem confiança por minuto de CI.

Para quem está montando portfólio, um bom projeto é pegar uma lib pequena com 3–4 features, quebrar de propósito uma combinação e mostrar no README o job de `cargo-hack` que captura a regressão. Isso combina bem com o discurso de [carreira em Rust](/blog/carreira-rust-2026/) e com práticas de [testes em Rust](/blog/testes-rust-estrategias-boas-praticas-2026/).

## Perguntas frequentes

### O cargo-hack altera meu Cargo.toml?

Não. Ele orquestra comandos e combinações; a fonte da verdade continua sendo o `Cargo.toml`, os targets e a CI.

### Preciso rodar powerset em todo pull request?

Na maioria dos projetos, não. Prefira `--each-feature` no PR e deixe powerset limitado para nightly, main ou pré-release.

### E se meu projeto não tiver features opcionais?

Provavelmente você não precisa do `cargo-hack` agora. A ferramenta brilha quando existe matriz. Sem flags, invista em testes, lint e boa política de dependências.

### Posso usar cargo-hack só com check e nunca testar features?

Pode como primeiro passo, mas é incompleto se o comportamento runtime depende de `cfg(feature = ...)`. Compile cedo, teste o que importa.

### Qual a relação com cargo-minimal-versions ou resoluções antigas?

São eixos diferentes. `cargo-hack` cobre features/pacotes/toolchains; políticas de versões mínimas de dependências resolvem outro risco de compatibilidade. Em crates sérios, os dois eixos aparecem cedo ou tarde.

## Conclusão

Feature flags são parte do produto em Rust, não um detalhe de `Cargo.toml`. O `cargo-hack` transforma essa matriz em verificação automatizada: `--each-feature` para o dia a dia, powerset controlado para interações reais, workspace consciente do que é publicado, e CI em camadas para não pagar custo de release em todo commit.

Adote a ferramenta quando o crate já tiver — ou estiver prestes a ter — mais de um caminho de build relevante. Comece barato, documente o contrato, exclua o inválido e só então expanda a matriz.

Continue a trilha de tooling com [cargo-nextest](/blog/cargo-nextest-testes-rust-2026/), [cargo-msrv](/blog/cargo-msrv-versao-minima-rust-ci-2026/), [cargo-semver-checks](/blog/cargo-semver-checks-rust-api-ci-2026/), [cargo-machete e cargo-udeps](/blog/cargo-machete-cargo-udeps-dependencias-nao-usadas-2026/) e [segurança de supply chain com cargo-deny](/blog/rust-seguranca-supply-chain-cargo-deny-sbom-2026/). Juntas, essas peças ajudam a entregar crates que compilam no seu laptop, na CI e no projeto de quem depende de você.
