Introdução
O Rust 1.94.0, lançado em 5 de março de 2026, trouxe uma safra excelente de estabilizações que impactam desde quem trabalha com processamento de sinais até quem mantém grandes projetos com o Cargo. Neste artigo, vamos explorar cada recurso novo, com exemplos de código prontos para você copiar e testar.
Se você ainda não atualizou, basta rodar:
// No terminal:
// rustup update stable
Vamos às novidades!
array_windows: Iteração Tipada sobre Slices
O método array_windows é, sem dúvida, o destaque desta release. Ele funciona de forma semelhante ao já conhecido windows(), mas retorna referências a arrays de tamanho fixo (&[T; N]) em vez de slices dinâmicos (&[T]).
fn main() {
let dados = [10, 20, 30, 40, 50, 60];
// Com windows() — retorna &[i32] (tamanho dinâmico)
for janela in dados.windows(3) {
println!("slice: {:?}", janela);
}
// Com array_windows() — retorna &[i32; 3] (tamanho fixo!)
for janela in dados.array_windows::<3>() {
let [a, b, c] = *janela;
println!("a={}, b={}, c={}", a, b, c);
}
}
Por que isso importa?
Quando o compilador sabe o tamanho exato da janela em tempo de compilação, ele pode eliminar verificações de limites (bounds checks) automaticamente. Para quem faz processamento numérico, isso significa ganho de performance sem nenhum unsafe:
fn media_movel(valores: &[f64]) -> Vec<f64> {
valores
.array_windows::<5>()
.map(|janela| {
let soma: f64 = janela.iter().sum();
soma / 5.0
})
.collect()
}
fn main() {
let precos = vec![100.0, 102.5, 101.0, 103.0, 105.5, 104.0, 106.0];
let medias = media_movel(&precos);
println!("Médias móveis: {:?}", medias);
}
Se você trabalha com séries temporais, processamento de áudio, ou análise de dados em Rust, array_windows é um upgrade gratuito de performance. Confira também nosso artigo sobre otimização de performance para mais técnicas.
AVX-512 FP16 e NEON FP16 Estabilizados
O Rust 1.94 promove as intrinsics AVX-512 FP16 (x86) e NEON FP16 (AArch64) para estáveis. Isso significa que agora é possível usar instruções de ponto flutuante de meia precisão (16 bits) sem a flag nightly.
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
#[cfg(target_arch = "x86_64")]
fn soma_fp16_avx512(a: &[u16], b: &[u16]) -> Vec<u16> {
// Exemplo conceitual — requer CPU com suporte AVX-512 FP16
// (Intel Sapphire Rapids ou posterior)
assert_eq!(a.len(), b.len());
a.iter()
.zip(b.iter())
.map(|(&x, &y)| x.wrapping_add(y))
.collect()
}
Embora o uso direto de intrinsics seja mais comum em bibliotecas especializadas, a estabilização abre caminho para crates de machine learning e processamento de imagem aproveitarem FP16 nativo. Se você se interessa por IA em Rust, confira nosso post sobre Rust e inteligência artificial.
Para quem desenvolve para sistemas embarcados com processadores ARM, o suporte NEON FP16 estável é igualmente importante — especialmente em dispositivos IoT com restrições de memória.
TOML 1.1 no Cargo
O Cargo agora parseia TOML v1.1 nos manifestos (Cargo.toml) e arquivos de configuração. As principais melhorias incluem:
# Cargo.toml — agora com TOML 1.1
[package]
name = "meu-projeto"
version = "0.1.0"
edition = "2024"
# TOML 1.1: datas sem offset de timezone
criado = 2026-03-05
# TOML 1.1: strings com escape \x para bytes hex
[package.metadata]
prefixo = "\x1B[32m" # escape ANSI verde
Além disso, o Cargo 1.94 introduziu a chave include no topo do arquivo de configuração, permitindo compartilhar configurações entre projetos:
# .cargo/config.toml
include = ["../../shared-cargo-config.toml"]
[build]
jobs = 8
Isso é especialmente útil em workspaces com muitos crates, onde manter configurações DRY economiza tempo e evita erros.
Novas APIs Estabilizadas
LazyCell e LazyLock Ganham Métodos
Os tipos LazyCell e LazyLock — muito úteis para inicialização preguiçosa — ganharam métodos get, get_mut e force_mut:
use std::cell::LazyCell;
fn main() {
let valor = LazyCell::new(|| {
println!("Inicializando...");
42
});
// Verifica se já foi inicializado sem forçar
assert!(LazyCell::get(&valor).is_none());
// Agora força a inicialização
println!("Valor: {}", *valor);
// get() agora retorna Some
assert_eq!(LazyCell::get(&valor), Some(&42));
}
Para a versão thread-safe com LazyLock, o padrão é idêntico:
use std::sync::LazyLock;
static CONFIG: LazyLock<String> = LazyLock::new(|| {
std::fs::read_to_string("config.toml")
.unwrap_or_else(|_| String::from("default"))
});
fn main() {
// Verifica sem inicializar
if LazyLock::get(&CONFIG).is_none() {
println!("Config ainda não carregada");
}
// Acessa e inicializa
println!("Config: {}", *CONFIG);
}
Confira também nosso conteúdo sobre OnceCell e OnceLock na standard library.
Constantes Matemáticas: EULER_GAMMA e GOLDEN_RATIO
Duas novas constantes foram adicionadas tanto para f32 quanto para f64:
fn main() {
// Constante de Euler-Mascheroni (γ ≈ 0.5772)
let gamma_64 = f64::EULER_GAMMA;
let gamma_32 = f32::EULER_GAMMA;
// Proporção áurea (φ ≈ 1.6180)
let phi_64 = f64::GOLDEN_RATIO;
let phi_32 = f32::GOLDEN_RATIO;
println!("Euler-Mascheroni: {gamma_64}");
println!("Proporção áurea: {phi_64}");
println!("f32 — γ: {gamma_32}, φ: {phi_32}");
}
Essas constantes são úteis em computação científica, análise numérica e algoritmos matemáticos. Anteriormente, era necessário defini-las manualmente ou depender de crates externos.
Peekable::next_if_map
O novo método next_if_map no iterador Peekable permite espiar e transformar condicionalmente o próximo elemento:
fn main() {
let numeros = vec!["42", "abc", "7", "xyz", "100"];
let mut iter = numeros.iter().peekable();
let mut resultado = Vec::new();
while iter.peek().is_some() {
// Tenta converter; se funcionar, consome o elemento
if let Some(n) = iter.next_if_map(|s| s.parse::<i32>().ok()) {
resultado.push(n);
} else {
// Pula elementos não numéricos
iter.next();
}
}
println!("Números parseados: {:?}", resultado);
// Saída: [42, 7, 100]
}
Isso simplifica muito o código de parsers e lexers que precisam consumir tokens condicionalmente.
element_offset para Slices
O método element_offset permite descobrir o índice de um elemento dentro de um slice a partir de sua referência:
fn main() {
let dados = [10, 20, 30, 40, 50];
let slice = &dados[..];
let elemento = &slice[2]; // referência ao 30
let offset = slice.element_offset(elemento);
println!("Offset: {:?}", offset); // Some(2)
}
Guia de Migração
A atualização para o Rust 1.94 é tranquila para a maioria dos projetos. Pontos de atenção:
- TOML 1.1: Se seu
Cargo.tomlusava workarounds para limitações do TOML 1.0, revise — pode simplificar. - Clippy: Novos lints foram adicionados. Rode
cargo clippyapós atualizar e corrija avisos. - MSRV: Se mantém uma Minimum Supported Rust Version, atualize a documentação.
# Atualizar toolchain
rustup update stable
# Verificar compatibilidade
cargo check
cargo clippy
cargo test
Confira nosso guia sobre CI/CD com Rust para automatizar essas verificações em seu pipeline.
Conclusão
O Rust 1.94 é uma release que reforça a maturidade da linguagem: array_windows melhora a ergonomia e performance de código numérico, as estabilizações de LazyCell/LazyLock simplificam padrões de inicialização preguiçosa, e o suporte a TOML 1.1 moderniza o Cargo.
Se você quer começar com Rust, confira nosso guia de como aprender Rust em 2026. Para quem já programa, aproveite também nosso tutorial sobre primeiros passos e o cheatsheet completo.
Acompanhe o Rust Brasil para ficar por dentro das próximas releases!
Leia também:
- Ecossistema Rust em 2026
- Async Rust: O Ecossistema em 2026
- Testes em Rust: Estratégias e Boas Práticas em 2026
- Compilação Condicional com cfg e Features
Fontes externas:
Veja também nossos sites parceiros:
- Go Brasil — para quem também se interessa por Go, outra linguagem de sistemas
- Python Brasil Dev — se você está migrando de Python para Rust
- Zig Brasil — para quem acompanha linguagens de sistemas modernas