A equipa do Rust tem o prazer de anunciar uma nova versão do Rust, 1.78.0. Rust é uma linguagem de programação que capacita todos a construir software confiável e eficiente.
\ Se você tem uma versão anterior do Rust instalada via rustup, pode obter a 1.78.0 com:
$ rustup update stable
\ Se ainda não o tem, pode obter o rustup na página apropriada do nosso website, e verificar as notas de lançamento detalhadas para 1.78.0.
\ Se quiser ajudar-nos testando versões futuras, pode considerar atualizar localmente para usar o canal beta (rustup default beta) ou o canal nightly (rustup default nightly). Por favor, reporte quaisquer bugs que encontre!
O Rust agora suporta um namespace de atributo #[diagnostic] para influenciar mensagens de erro do compilador. Estes são tratados como dicas que o compilador não é obrigado a usar, e também não é um erro fornecer um diagnóstico que o compilador não reconheça. Esta flexibilidade permite que o código fonte forneça diagnósticos mesmo quando não são suportados por todos os compiladores, sejam eles versões diferentes ou implementações completamente diferentes.
\ Com este namespace vem o primeiro atributo suportado, #[diagnostic::on_unimplemented], que pode ser colocado num trait para personalizar a mensagem quando esse trait é necessário mas não foi implementado num tipo. Considere o exemplo dado no pull request de estabilização:
#[diagnostic::on_unimplemented( message = "My Message for `ImportantTrait<{A}>` is not implemented for `{Self}`", label = "My Label", note = "Note 1", note = "Note 2" )] trait ImportantTrait<A> {} fn use_my_trait(_: impl ImportantTrait<i32>) {} fn main() { use_my_trait(String::new()); }
\ Anteriormente, o compilador daria um erro integrado como este:
error[E0277]: the trait bound `String: ImportantTrait<i32>` is not satisfied --> src/main.rs:12:18 | 12 | use_my_trait(String::new()); | ------------ ^^^^^^^^^^^^^ the trait `ImportantTrait<i32>` is not implemented for `String` | | | required by a bound introduced by this call |
\ Com #[diagnostic::on_unimplemented], a sua mensagem personalizada preenche a linha de erro principal, e a sua etiqueta personalizada é colocada na saída da fonte. A etiqueta original ainda é escrita como saída de ajuda, e quaisquer notas personalizadas também são escritas. (Estes detalhes exatos estão sujeitos a alterações.)
error[E0277]: My Message for `ImportantTrait<i32>` is not implemented for `String` --> src/main.rs:12:18 | 12 | use_my_trait(String::new()); | ------------ ^^^^^^^^^^^^^ My Label | | | required by a bound introduced by this call | = help: the trait `ImportantTrait<i32>` is not implemented for `String` = note: Note 1 = note: Note 2
\ Para autores de traits, este tipo de diagnóstico é mais útil se puder fornecer uma dica melhor do que apenas falar sobre a implementação ausente em si. Por exemplo, esta é uma amostra abreviada da biblioteca padrão:
#[diagnostic::on_unimplemented( message = "the size for values of type `{Self}` cannot be known at compilation time", label = "doesn't have a size known at compile-time" )] pub trait Sized {}
\ Para mais informações, consulte a secção de referência sobre o namespace de atributo da ferramenta diagnostic.
unsafeA biblioteca padrão do Rust tem várias afirmações para as pré-condições de funções unsafe, mas historicamente elas só foram habilitadas em compilações #[cfg(debug_assertions)] da biblioteca padrão para evitar afetar o desempenho da versão de lançamento. No entanto, como a biblioteca padrão geralmente é compilada e distribuída em modo de lançamento, a maioria dos desenvolvedores Rust nunca executava essas verificações.
\ Agora, a condição para essas afirmações é adiada até a geração de código, então elas serão verificadas dependendo da configuração do próprio usuário para afirmações de depuração -- habilitadas por padrão em compilações de depuração e teste. Esta mudança ajuda os usuários a capturar comportamento indefinido em seu código, embora os detalhes de quanto é verificado geralmente não sejam estáveis.
\ Por exemplo, slice::from_raw_parts requer um ponteiro não-nulo alinhado. O uso a seguir de um ponteiro propositalmente desalinhado tem comportamento indefinido, e embora se você tivesse azar poderia ter parecido "funcionar" no passado, a afirmação de depuração agora pode capturá-lo:
fn main() { let slice: &[u8] = &[1, 2, 3, 4, 5]; let ptr = slice.as_ptr(); // Create an offset from `ptr` that will always be one off from `u16`'s correct alignment let i = usize::from(ptr as usize & 1 == 0); let slice16: &[u16] = unsafe { std::slice::from_raw_parts(ptr.add(i).cast::<u16>(), 2) }; dbg!(slice16); } thread 'main' panicked at library/core/src/panicking.rs:220:5: unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX` note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace thread caused non-unwinding panic. aborting.
A biblioteca padrão tem algumas funções que alteram o alinhamento de ponteiros e slices, mas anteriormente tinham ressalvas que as tornavam difíceis de confiar na prática, se você seguisse sua documentação com precisão. Essas ressalvas existiam principalmente como uma proteção contra avaliação const, mas elas só são estáveis para uso não-const de qualquer forma. Agora, promete-se que elas terão um comportamento de tempo de execução consistente de acordo com suas entradas reais.
pointer::align_offset calcula o deslocamento necessário para alterar um ponteiro para o alinhamento dado. Retorna usize::MAX se isso não for possível, mas anteriormente era permitido sempre retornar usize::MAX, e agora esse comportamento foi removido.slice::align_to e slice::align_to_mut ambos transmutam slices para um slice do meio alinhado e os slices de cabeça e cauda não alinhados restantes. Esses métodos agora prometem retornar a maior parte do meio possível, em vez de permitir que a implementação retorne algo menos ideal, como retornar tudo como o slice de cabeça.impl Read for &Stdin'static para várias implementações relacionadas a std::error::Errorimpl<Fd: AsFd> impl aceitar ?Sizedimpl From<TryReserveError> for io::Error\ Estas APIs agora são estáveis em contextos const:
Barrier::new()x86_64-pc-windows-msvci686-pc-windows-msvcx86_64-pc-windows-gnui686-pc-windows-gnux86_64-pc-windows-gnullvmi686-pc-windows-gnullvmu128/i128 anunciada para alvos x86-32 e x86-64. Distribuidores que usam seu próprio LLVM mais antigo que 18 ainda podem enfrentar os bugs de convenção de chamada mencionados nesse post.Confira tudo o que mudou no Rust, Cargo e Clippy.
Muitas pessoas se uniram para criar o Rust 1.78.0. Não poderíamos tê-lo feito sem todos vocês. Obrigado!
A Equipa de Lançamento do Rust
\ Também publicado aqui
\ Foto de Ubaid E. Alyafizi no Unsplash


