Rust 1.88: Let Chains, Naked Functions e Novidades — 2026

Conheça as novidades do Rust 1.88: let chains para condicionais elegantes, naked functions para controle total de assembly e limpeza automática do cache do Cargo.

Introdução

O Rust 1.88.0, lançado em junho de 2025, trouxe recursos que desenvolvedores pediam há anos. Os let chains simplificam condicionais complexas, as naked functions abrem as portas para programação de baixo nível sem overhead do compilador, e o Cargo ganhou limpeza automática de cache. Se você acompanhou as novidades do Rust 1.86 e 1.87, vai perceber que o ritmo de melhorias segue acelerado.

Neste artigo, exploramos cada recurso com exemplos práticos para você aplicar no seu dia a dia.


Let Chains: Condicionais Mais Elegantes

Antes do Rust 1.88, combinar múltiplos if let com condições booleanas exigia aninhamento excessivo:

// Antes do Rust 1.88 — aninhamento doloroso
fn processar_pedido(pedido: Option<Pedido>) {
    if let Some(p) = pedido {
        if let StatusPedido::Aprovado(valor) = p.status {
            if valor > 100.0 {
                println!("Pedido aprovado de alto valor: R${:.2}", valor);
            }
        }
    }
}

Com let chains, você encadeia let e expressões booleanas com && em uma única condição:

// Rust 1.88+ — let chains
fn processar_pedido(pedido: Option<Pedido>) {
    if let Some(p) = pedido
        && let StatusPedido::Aprovado(valor) = p.status
        && valor > 100.0
    {
        println!("Pedido aprovado de alto valor: R${:.2}", valor);
    }
}

O código fica mais linear, mais legível e elimina o “triângulo da indentação”. As variáveis vinculadas em cada let ficam disponíveis nas condições seguintes e no corpo do bloco.

Let Chains em while

O recurso também funciona com while, o que é útil para processar iteradores com condições compostas:

use std::collections::VecDeque;

struct Tarefa {
    prioridade: u8,
    descricao: String,
    concluida: bool,
}

fn processar_fila(fila: &mut VecDeque<Tarefa>) {
    while let Some(tarefa) = fila.front()
        && !tarefa.concluida
        && tarefa.prioridade >= 5
    {
        let tarefa = fila.pop_front().unwrap();
        println!("Processando: {}", tarefa.descricao);
    }
}

Requisito: Edition 2024

Os let chains exigem a Rust Edition 2024 (disponível a partir do Rust 1.85). Isso ocorre porque o recurso depende de mudanças na ordem de drop de temporários em if let. Para migrar, atualize seu Cargo.toml:

[package]
edition = "2024"

E rode cargo fix --edition para aplicar correções automáticas. O Cargo cuida da maior parte da migração.


Naked Functions: Controle Total do Assembly

Para quem trabalha com sistemas embarcados, kernels ou runtime de baixo nível, as naked functions são uma adição transformadora. Uma função naked não recebe prólogo nem epílogo gerados pelo compilador — você escreve o assembly diretamente:

use core::arch::naked_asm;

#[unsafe(naked)]
unsafe extern "C" fn soma_assembly(a: u64, b: u64) -> u64 {
    naked_asm!(
        "lea rax, [rdi + rsi]",
        "ret"
    )
}

fn main() {
    let resultado = unsafe { soma_assembly(10, 32) };
    println!("Resultado: {}", resultado); // 42
}

Quando Usar Naked Functions?

Naked functions são essenciais em cenários onde o compilador não pode gerar o código correto:

  • Handlers de interrupção em sistemas embarcados e IoT com Embassy
  • Trampolins de contexto em runtimes async ou sistemas operacionais
  • Funções de boot que precisam de controle exato do stack
  • Wrappers para ABIs exóticas que o Rust não suporta nativamente
  • Builtins do compilador como os usados no compiler-builtins

Aqui está um exemplo mais realista de um handler de interrupção para um sistema embarcado:

#[unsafe(naked)]
unsafe extern "C" fn interrupt_handler() {
    naked_asm!(
        // Salvar registradores no stack
        "push rax",
        "push rbx",
        "push rcx",
        // Chamar o handler real em Rust
        "call rust_interrupt_handler",
        // Restaurar registradores
        "pop rcx",
        "pop rbx",
        "pop rax",
        "iretq"
    )
}

extern "C" fn rust_interrupt_handler() {
    // Lógica em Rust seguro
    // ...
}

Se você vem de C e está migrando código que usa __attribute__((naked)) do GCC, a equivalência em Rust agora é direta. Veja nosso artigo sobre Rust vs C++ para mais detalhes sobre a transição.


Literais Booleanos em cfg

O predicado cfg agora aceita true e false como literais. Pode parecer simples, mas elimina hacks comuns:

// Antes: truques para desabilitar código temporariamente
#[cfg(any())]  // "sempre falso" — pouco legível
fn funcao_desabilitada() {}

#[cfg(all())]  // "sempre verdadeiro" — confuso
fn funcao_habilitada() {}

// Rust 1.88+: intenção clara
#[cfg(false)]
fn funcao_desabilitada() {}

#[cfg(true)]
fn funcao_habilitada() {}

Isso é particularmente útil durante desenvolvimento e debugging, quando você quer desabilitar temporariamente um módulo sem comentar código. Combine com compilação condicional para estratégias mais avançadas.


Limpeza Automática de Cache do Cargo

O Cargo agora executa garbage collection automaticamente no diretório ~/.cargo. As regras são:

Tipo de arquivoTempo de inatividadeAção
Crates baixados da rede3 mesesRemovidos automaticamente
Artefatos de build locais1 mêsRemovidos automaticamente

Você pode configurar os intervalos no arquivo ~/.cargo/config.toml:

[cache]
auto-clean-frequency = "1 week"

[cache.downloads]
max-age = "2 months"

[cache.builds]
max-age = "2 weeks"

Para quem mantém máquinas de CI com caches que crescem indefinidamente, esse recurso é um alívio. Em projetos grandes com Cargo workspaces, o diretório ~/.cargo pode facilmente passar de 10 GB — agora isso é gerenciado automaticamente.


APIs Estabilizadas

O Rust 1.88 estabilizou 19 APIs. Algumas das mais úteis:

Cell::update

Permite modificar o valor de um Cell in-place com uma closure:

use std::cell::Cell;

let contador = Cell::new(0);
contador.update(|v| v + 1);
assert_eq!(contador.get(), 1);

Saiba mais sobre Cell e RefCell na nossa referência da biblioteca padrão.

HashMap::extract_if e HashSet::extract_if

Remove e retorna elementos que satisfazem um predicado:

use std::collections::HashMap;

let mut mapa: HashMap<&str, i32> = HashMap::from([
    ("rust", 95),
    ("go", 80),
    ("python", 75),
    ("c", 70),
]);

// Extrair linguagens com nota acima de 80
let top: HashMap<&str, i32> = mapa.extract_if(|_k, v| *v > 80).collect();

println!("Top linguagens: {:?}", top);    // {"rust": 95}
println!("Restantes: {:?}", mapa);         // {"go": 80, "python": 75, "c": 70}

Consulte nosso guia sobre HashMap para mais padrões de uso.

Métodos de Chunking em Slices

as_chunks e as_rchunks dividem slices em arrays de tamanho fixo em tempo de compilação:

let dados = [1, 2, 3, 4, 5, 6, 7];

let (chunks, resto) = dados.as_chunks::<3>();
assert_eq!(chunks, &[[1, 2, 3], [4, 5, 6]]);
assert_eq!(resto, &[7]);

Veja mais sobre slices e arrays na documentação da stdlib.


Como Atualizar

Para atualizar o Rust no seu sistema, use o rustup:

rustup update stable

Para verificar sua versão:

rustc --version
# rustc 1.88.0 (algum-hash 2025-06-26)

Se ainda não tem o Rust instalado, confira nosso guia de instalação no Ubuntu ou instalação no macOS.


Perguntas Frequentes

O que são let chains no Rust?

Let chains permitem encadear múltiplas expressões let com && em condições if e while, eliminando a necessidade de blocos aninhados. Cada variável vinculada fica disponível nas condições seguintes e no corpo do bloco.

Preciso da Edition 2024 para usar let chains?

Sim. Let chains exigem a Rust Edition 2024 ou posterior devido a mudanças na ordem de drop de temporários. Atualize o campo edition no seu Cargo.toml para "2024" e rode cargo fix --edition.

Para que servem naked functions?

Naked functions eliminam o prólogo e epílogo gerados pelo compilador, permitindo controle total do assembly. São usadas em handlers de interrupção, boot code e situações onde o layout exato do stack importa.

O que mudou no cache do Cargo?

O Cargo 1.88 limpa automaticamente crates baixados após 3 meses de inatividade e artefatos locais após 1 mês. Os intervalos podem ser configurados em ~/.cargo/config.toml.


Conclusão

O Rust 1.88 continua a tendência de tornar a linguagem mais ergonômica sem sacrificar performance ou segurança. Os let chains resolvem uma frustração antiga da comunidade, as naked functions abrem portas para mais casos de uso de baixo nível, e a limpeza automática do Cargo é daquelas melhorias silenciosas que fazem diferença no dia a dia.

Se você quer se aprofundar nos fundamentos que sustentam esses recursos, explore nossos tutoriais de Rust e a referência completa da biblioteca padrão. Para quem está considerando Rust para projetos novos, compare com outras linguagens nos nossos artigos Go, Kotlin e Zig.

Leia Também