Pular para o conteúdo

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.

Por Tech AI Wire Team

4 min de leitura

XLinkedIn
Screenshot of the Rust Blog post 'Announcing Rust 1.99.0', dated October 1, 2026, from the Rust Release Team.

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:

ÁreaMudança
PlataformasLinux RISC-V de 64 bits com musl sobe para o suporte Tier 2
LinkagemExecutáveis estáticos independentes de posição são habilitados nos targets GNU e musl
RustdocFiltrar implementações de traits fica cerca de 20% mais rápido em média, até 40% em alguns crates
MacrosMacros de atributo agora funcionam em módulos definidos em um arquivo separado, como #[my_macro] mod foo;
Assembly inlineInteiros 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çaDetalhe
#[no_mangle] em itens genéricosAgora é um erro definitivo; gerava aviso desde o Rust 1.56, segundo o ByteIOTA
Módulos de inteiros legadosAgora totalmente obsoletos
Statics externosEmpréstimos não são mais promovidos automaticamente a 'static, relata o ByteIOTA
Blocos de código em comentários de documentaçãoOs atributos neles precisam ter alvos válidos, ou o build da documentação falha
RangeInclusiveA iteração está mais otimizada, o que muda o comportamento de um intervalo já esgotado
Pin::new_uncheckedSuas 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

  1. Announcing Rust 1.99.0 - Rust Blog
  2. Rust 1.99.0 Ships with Stable C-Variadic Functions - Linux Compatible
  3. Rust 1.99 Is Out: C-Variadics and What Breaks - ByteIOTA
  4. 1.99.0 - releases.rs

Artigos relacionados