1 pontos por GN⁺ 4 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Rust 1.96.0 pode ser instalado com rustup update stable, e a validação de futuras releases pode ser feita nos canais beta/nightly
  • Os novos tipos core::range::Range* implementam IntoIterator em vez de Iterator, o que permite implementar Copy e deve torná-los os tipos padrão da sintaxe de intervalos no futuro
  • assert_matches! e debug_assert_matches! agora exibem também a representação Debug do valor quando o padrão não corresponde, facilitando o diagnóstico de falhas em testes
  • Os alvos WebAssembly não passam mais --allow-undefined por padrão, então símbolos indefinidos agora geram erro de linker em vez de virar imports
  • O Cargo inclui correções para CVE-2026-5223 e CVE-2026-5222 para usuários de registros de terceiros; usuários do crates.io não são afetados

Principais mudanças no Rust 1.96.0

  • Atualização e canais de teste

  • Novos tipos Range*

    • O Range existente e os tipos relacionados em core::ops são algo que muitos usuários esperam que seja Copy, mas eles não implementavam Copy porque implementam Iterator diretamente
    • Implementar Iterator e Copy ao mesmo tempo no mesmo tipo é uma armadilha apontada pelo Clippy, por isso isso vinha sendo evitado
    • A RFC3550 propôs tipos alternativos de intervalo que implementam IntoIterator em vez de Iterator, e nessa estrutura esses tipos também podem implementar Copy
    • Na biblioteca padrão, foram estabilizados core::range::Range, core::range::RangeFrom, core::range::RangeInclusive e os iteradores relacionados
    • Em uma versão próxima do Rust, também devem ser adicionados core::range::RangeFull e core::range::RangeTo, reexportados de core::ops, além de core::range::legacy::*, que será o novo local dos tipos de intervalo atuais
    • A sintaxe de intervalos, como 0..1, hoje cria tipos legados, mas em uma edição futura passará a usar os tipos de core::range
    • Com essa nova estabilização, passa a ser possível armazenar indexadores de slice em tipos Copy sem precisar separar start e end
    • Exemplo:
      use core::range::Range;
      
      #[derive(Clone, Copy)]
      pub struct Span(Range<usize>);
      
      impl Span {
          pub fn of(self, s: &str) -> &str {
              &s[self.0]
          }
      }
      
    • O novo RangeInclusive expõe seus campos, já que não há necessidade de evitar, como na versão legada, a exposição do estado de iterador esgotado
    • Como os novos tipos precisam primeiro ser convertidos antes de iniciar a iteração, campos públicos não se tornam um problema
    • Autores de bibliotecas devem considerar usar impl RangeBounds em APIs públicas para aceitar tanto os tipos legados quanto os novos tipos de intervalo
    • Se for necessário um tipo concreto, a recomendação é preferir os novos tipos de intervalo, que devem se tornar o padrão no futuro
  • Macros de asserção para pattern matching

    • As novas macros assert_matches! e debug_assert_matches! verificam se um valor corresponde a um padrão e, se não corresponder, fazem panic junto com a representação Debug desse valor
    • As duas macros são essencialmente equivalentes a assert!(matches!(..)) e debug_assert!(matches!(..)), mas o valor mostrado em caso de falha melhora a capacidade de diagnóstico
    • Como podem entrar em conflito com crates populares de terceiros que já oferecem macros com o mesmo nome, elas não foram adicionadas ao prelúdio padrão
    • Antes de usar, é preciso importá-las diretamente de core ou std
    • Exemplo:
      use core::assert_matches;
      
      /// [Random Number](https://xkcd.com/221/)
      fn get_random_number() -> u32 {
          // chosen by a fair dice roll.
          // guaranteed to be random.
          4
      }
      
      fn main() {
          assert_matches!(get_random_number(), 1..=6);
      }
      
  • Mudança nos alvos WebAssembly

    • Os alvos WebAssembly não passam mais --allow-undefined para o linker
    • Durante a linkedição, símbolos indefinidos não são mais convertidos em imports WebAssembly do módulo "env"; agora isso gera erro de linker
    • Como o módulo não será linkado se todos os símbolos relacionados à linkedição não estiverem definidos, isso ajuda a detectar bugs mais cedo e evita problemas acidentais causados, por exemplo, por nomes de símbolos
    • Símbolos indefinidos relacionados à linkedição normalmente indicam um bug em tempo de build ou um erro de configuração
    • Se o comportamento antigo era intencional, ele pode ser restaurado com RUSTFLAGS=-Clink-arg=--allow-undefined, ou pode-se usar #[link(wasm_import_module = "env")] no bloco que define o símbolo no código-fonte
    • Essa mudança passa a valer no Rust 1.96 após o aviso anterior no blog

APIs estabilizadas e correções de segurança

1 comentários

 
GN⁺ 4 시간 전
Opiniões no Lobste.rs
  • Eu sempre acabo querendo assert_matches, e toda vez fico em dúvida se adiciono mais um crate ou se reimplemento por conta própria
    Então fico feliz em vê-lo entrando na biblioteca padrão

    • É estranho estar animado com a possibilidade de apagar centenas de pares de parênteses nos testes? Eu diria que não
  • Gosto da etapa de transformar ranges em tipos Copy
    Já me surpreendi algumas vezes por precisar clonar ranges, e isso também combina melhor com a intuição de que 12..34 deveria ser um dado pequeno e copiável
    Só fico um pouco preocupado que, se começarem a existir vários tipos com o mesmo nome, o VS Code acabe importando o tipo errado na próxima vez que adicionar automaticamente uma declaração use

    A Rust version in the near future will also add [...] core::range::legacy::* as the new home for the current ranges. Range syntax like 0..1 still produces the legacy types for now, but will be updated to core::range types in a future edition.
    O sistema de editions do Rust parece uma ideia bem boa

    • Pelo que eu sei, quando há ambiguidade nas importações, a ação de código do VS Code deveria abrir um menu suspenso para você escolher qual usar
    • Acho que não vai ser necessário importar esse tipo com frequência no dia a dia
      Para a maioria dos usuários, a vantagem dos novos tipos é pequena, então dá para continuar usando os tipos antigos, e na fronteira da próxima edition os novos tipos passarão a ser usados automaticamente
      Imagino que quem mais vai importar esses tipos serão autores de bibliotecas que queiram dar suporte explícito às duas versões
  • These new macros have not been added to the standard prelude, because they would collide with popular third-party crates that provide macros with the same name. Instead, they should be manually imported from core or std before use.
    Isso parece meio estranho
    Será que existe plano para mudar isso depois? Parece o tipo de coisa que daria para ajustar mais tarde, como uma limpeza pequena, depois que o ecossistema tiver migrado, digamos, em uns 3 anos

    • É aí que editions ajudam
      Dá para mudar o prelude sem quebrar projetos existentes