Rust 1.99 estabiliza a definição de funções C-variadic
O Rust 1.99.0, lançado em 1º de outubro de 2026, permite que o Rust estável defina funções C-variadic como printf, passa para o LLVM 23 e torna no_mangle em genéricos um erro.
4 min de leitura

Em números
- new code-generation backend
- LLVM 23
- average Rustdoc speedup on trait impl filtering
- 20%
- best-case Rustdoc speedup on some crates
- 40%
- release that first warned about no_mangle on generics
- 1.56
A equipe do Rust lançou o Rust 1.99.0 em 1º de outubro de 2026. A principal mudança permite que o Rust estável defina funções C-variadic, o tipo de função que aceita qualquer número de argumentos, como o printf do C. Isso fecha uma lacuna para o código Rust que precisa trabalhar lado a lado com C.
A versão também leva o compilador ao LLVM 23, acelera a ferramenta de documentação e transforma um aviso antigo em erro definitivo.
O que as definições C-variadic acrescentam
Uma função variádica aceita um número variável de argumentos. O C as usa amplamente, e o Rust há muito tempo consegue chamá-las. Definir uma em Rust era outra história. "O Rust já podia chamar funções variádicas definidas externamente (por exemplo, libc::printf). Com o Rust 1.99, essas funções agora podem ser escritas no próprio Rust", diz o anúncio oficial.
A sintaxe usa ... como último parâmetro. O ByteIOTA mostra a forma de uma definição como unsafe extern "C" fn my_logger(count: u32, mut args: ...) -> i32. Dentro da função, os argumentos extras chegam como um core::ffi::VaList, que, segundo o blog do Rust, é compatível com o tipo va_list do C no nível binário. O Linux Compatible relata que o código lê cada argumento com next_arg::<T>().
Um trait chamado VaArgSafe controla quais tipos podem passar. Ele marca os tipos que podem ser lidos com segurança da lista de argumentos, o que ajuda a evitar incompatibilidades de tipo. A versão também permite que funções naked usem assinaturas variádicas, segundo o blog do Rust e o releases.rs. Uma função naked é aquela que o compilador emite sem código de preparação. Código de baixo nível e embarcado a usa para controlar com exatidão a convenção de chamada.
Novas APIs de biblioteca estáveis
O blog do Rust lista estas entre as APIs agora disponíveis na versão estável:
- Layout de memória:
Layout::for_value_raw,mem::size_of_val_raw,mem::align_of_val_raw - Coleções e Box:
Box::into_non_null,Vec::into_parts,Vec::from_parts,VecDeque::retain_back - Sistema de arquivos:
std::fs::set_times,std::fs::set_times_nofollow
As funções set_times alteram os registros de data e hora de um arquivo a partir da biblioteca padrão. Como o nome sugere, a variante _nofollow não segue links simbólicos.
Mudanças no compilador, nas plataformas e nas ferramentas
O Rust 1.99 passa para o LLVM 23, a biblioteca de geração de código que transforma Rust em código de máquina. O ByteIOTA relata um corte médio de 1,2% no tempo real de compilação nos benchmarks, parte de um ganho de 4,57% em dois meses.
Outras mudanças, segundo o Linux Compatible e o releases.rs:
| Área | Mudança |
|---|---|
| Plataformas | Linux RISC-V de 64 bits com musl sobe para o suporte Tier 2 |
| Linkagem | Executáveis estáticos independentes de posição são habilitados nos targets GNU e musl |
| Rustdoc | Filtrar implementações de traits fica cerca de 20% mais rápido em média, até 40% em alguns crates |
| Macros | Macros de atributo agora funcionam em módulos definidos em um arquivo separado, como #[my_macro] mod foo; |
| Assembly inline | Inteiros de 128 bits podem ser passados em registradores vetoriais no x86 |
O Cargo, a ferramenta de build do Rust, recebe três mudanças. Ele reserva um novo perfil debug, que o releases.rs descreve como preparação para afastar o perfil dev da depuração "para dar um padrão mais sensato". Ele desativa a compilação incremental quando a variável de ambiente CI está definida, e o ByteIOTA observa que CARGO_INCREMENTAL=1 a reativa. Membros de workspace na edição 2024 também podem sobrescrever os padrões de dependências herdados.
O que pode quebrar
A versão traz várias mudanças de compatibilidade:
| Mudança | Detalhe |
|---|---|
#[no_mangle] em itens genéricos | Agora é um erro definitivo; gerava aviso desde o Rust 1.56, segundo o ByteIOTA |
| Módulos de inteiros legados | Agora totalmente obsoletos |
| Statics externos | Empréstimos não são mais promovidos automaticamente a 'static, relata o ByteIOTA |
| Blocos de código em comentários de documentação | Os atributos neles precisam ter alvos válidos, ou o build da documentação falha |
RangeInclusive | A iteração está mais otimizada, o que muda o comportamento de um intervalo já esgotado |
Pin::new_unchecked | Suas regras de segurança estão descritas com mais precisão |
Este é o passo mais recente em um ano movimentado para a linguagem. Em agosto, o Rust estabilizou o tipo never após dez anos, e as builds nightly ativaram o resolvedor de traits de nova geração.
O que isso significa para desenvolvedores
Apague seus shims de printf. Se você escreveu código C, ou usou um recurso nightly, só para aceitar argumentos variádicos de um chamador em C, agora pode fazer isso em Rust estável. Hosts de plugins, alocadores personalizados e pontes de logging são os lugares óbvios para olhar.
Verifique o código genérico em busca de #[no_mangle] antes de atualizar. Ele gera aviso desde o Rust 1.56, então um crate que ainda compila com esse aviso agora vai falhar. Procure o atributo em qualquer função genérica no seu código e nas suas dependências vendorizadas.
Fique de olho nos tempos de build da sua CI. O Cargo agora desativa a compilação incremental quando CI está definida. Normalmente essa é a decisão certa para builds limpos, mas uma configuração de CI que guarda em cache o diretório target entre execuções pode ficar mais lenta. Defina CARGO_INCREMENTAL=1 se as suas próprias medições indicarem isso.
Rode seus testes de documentação. Atributos obsoletos em blocos de código dentro de comentários de documentação agora fazem o build da documentação falhar. Rode cargo test --doc cedo para que um exemplo quebrado não bloqueie uma versão.
Teste o código que reutiliza intervalos já concluídos. A mudança em RangeInclusive só afeta intervalos que já foram iterados até o fim. Código que continua usando um intervalo assim depois do loop deve ser verificado em relação ao novo comportamento.
Fontes
- Announcing Rust 1.99.0 - Rust Blog
- Rust 1.99.0 Ships with Stable C-Variadic Functions - Linux Compatible
- Rust 1.99 Is Out: C-Variadics and What Breaks - ByteIOTA
- 1.99.0 - releases.rs
Artigos relacionados

Reescrita do mold em Rust quer ser o linker padrão do Linux
O mold faz a ligação 4,9 vezes mais rápido que o LLVM lld. Seu autor o está reescrevendo em Rust e quer que as distribuições o instalem como /usr/bin/ld.

Zig 0.17.0 traz um sistema de build dividido e rebuilds rápidos
O Zig 0.17.0 saiu em 2 de outubro com 925 commits de 206 colaboradores: um sistema de build reformulado, builds incrementais no Linux x86_64 e o LLVM 22.1.8.

Rust 1.100 remove as ferramentas de host dos alvos Windows de 32 bits
O Rust 1.100 deixa de distribuir o compilador para Windows de 32 bits. Os alvos i686 mantêm a biblioteca padrão, então a compilação cruzada a partir do Windows de 64 bits continua funcionando.