Versão Rust 1.40.0: # [não exaustiva], aprimoramentos de macro e outros aprimoramentos

A equipe Rust tem o prazer de anunciar o lançamento de uma nova versão, 1.40.0. Rust é uma linguagem de programação que permite a todos criar software confiável e eficiente.


Se você instalou a versão anterior do Rust usando rustup , para atualizar para a versão 1.40.0, basta executar o seguinte comando:


 $ rustup update stable 

Se você ainda não instalou o rustup , pode instalá-lo na página correspondente do nosso site, bem como ver notas de versão detalhadas no GitHub.


O que está incluído na versão estável 1.40.0


As principais inovações são a introdução do atributo #[non_exhaustive] , melhorias nas macros!() E #[attribute] . Por fim, os avisos do analisador de migração do mutuário se tornaram erros no Rust 2015. Consulte as notas de versão para obter mais informações.


#[non_exhaustive] estruturas, enumerações e opções de enumeração


Suponha que você seja o autor de uma biblioteca alpha que contém a pub struct Foo . Você gostaria de tornar públicos os campos da estrutura alpha::Foo , mas não tem certeza se precisará adicionar mais campos ao Foo em versões futuras. Um dilema surge: ou você torna os campos privados com inconvenientes subseqüentes ou corre o risco de colocar os usuários em dependência dos campos e depois viola o código deles ao adicionar novos. O Rust 1.40.0 apresenta uma maneira de resolver o problema com #[non_exhaustive] .


O atributo #[non_exhaustive] anexado à estrutura ou variante da enumeração e impede a comparação completa dos campos, a criação da referida estrutura ou variante fora da caixa com sua declaração. O exemplo a seguir demonstra erros na caixa beta dependente de alfa:


 // alpha/lib.rs: #[non_exhaustive] struct Foo { pub a: bool, } enum Bar { #[non_exhaustive] Variant { b: u8 } } fn make_foo() -> Foo { ... } fn make_bar() -> Bar { ... } // beta/lib.rs: let x = Foo { a: true }; //~  let Foo { a } = make_foo(); //~  let Foo { a, .. } = make_foo(); //~ OK // -- `beta`       . let x = Bar::Variant { a: 42 }; //~  let Bar::Variant { b } = make_bar(); //~  let Bar::Variant { b, .. } = make_bar(); //~ OK // -- `beta`    ... 

O que está acontecendo nos bastidores? A visibilidade dos construtores para a estrutura #[non_exhaustive] ou opção de enumeração será reduzida para pub(crate) , proibindo, assim, seu uso em engradados de terceiros.


Talvez um aspecto mais importante de #[non_exhaustive] seja que um atributo possa ser anexado às próprias enumerações. Aqui está o código obtido de std::cmp::Ordering :


 #[non_exhaustive] pub enum Ordering { Relaxed, Release, Acquire, AcqRel, SeqCst } 

Nesse caso, #[non_exhaustive] garante a possibilidade de adicionar novas opções no futuro. Isso é possível proibindo outros pacotes de usar uma correspondência exaustiva de imagens para Ordering . O compilador rejeitaria o seguinte:


 match ordering { Relaxed | Release | Acquire | AcqRel | SeqCst => { /* logic */ } //~^ ;      , //   ,        . } 

Em vez disso, agora outros pacotes devem considerar a possibilidade de novas opções de enumeração, por exemplo, adicionando o curinga _ :


 match ordering { Relaxed | Release | Acquire | AcqRel | SeqCst => { /* logic */ } _ => { /* logic */ } // OK;     ,   . } 

Detalhes sobre o atributo #[non_exhaustive] disponíveis no relatório de estabilização .


Aprimoramentos de macro e atributo


Na 1.40.0, fizemos várias melhorias nas macros e atributos, incluindo:


  • mac!() em contextos de tipo.


    Por exemplo, você pode escrever o type Foo = expand_to_type!(bar); onde expand_to_type será uma macro processual.


  • extern { ... } blocos extern { ... } .


    Este bloco inclui make_item!() . Por exemplo:


     macro_rules! make_item { ($name:ident) => { fn $name(); } } extern { make_item!(alpha); make_item!(beta); } 

    Agora, as macros processuais de atributo para elementos em blocos extern { ... } também são suportadas:


     extern "C" { #[my_identity_macro] //~  ,     `fn foo();`. fn foo(); } 

  • macro_rules! itens em macros procedurais.


    Macros com sintaxe de função ( mac!() ) E atributos ( #[mac] ) agora podem gerar macro_rules! . Veja o relatório de estabilização em anexo para mais detalhes.


  • TokenStream $m:meta suporta TokenStream .


    Ou seja, o seguinte código está correto:


     macro_rules! accept_meta { ($m:meta) => {} } accept_meta!( my::path ); accept_meta!( my::path = "lit" ); accept_meta!( my::path ( abc ) ); accept_meta!( my::path [ abc ] ); accept_meta!( my::path { abc } ); 


Avisos de migração do analisador do mutuário se tornam bugs na edição Rust 2015


No release 1.35.0, relatamos que o NLL apareceu na edição Rust 2015 após o primeiro lançamento da edição 2018 no Rust 1.31 .


Como dissemos, o antigo analisador de empréstimos poderia permitir um gerenciamento inseguro de memória e, com o novo analisador (verificador de empréstimos NLL), essas deficiências foram resolvidas. Como esses erros podem interromper o código estável, decidimos introduzi-los gradualmente, verificando se o analisador antigo permitirá a montagem do programa e se o novo irá bloqueá-lo. Nesses casos, os erros foram substituídos por avisos.


A versão anterior do Rust 1.39.0 substituiu esses avisos por erros de código na edição de 2018 . O Rust 1.40.0 aplicará as mesmas alterações no código da edição de 2015 , fechando permanentemente essas falhas de segurança. Junto com isso, o compilador foi limpo até do código antigo !


Se o seu projeto não ocorrer devido às alterações acima, ou se você quiser saber mais, leia a publicação de Niko Matsakis .


Funções mais constantes na biblioteca padrão


Começando com Rust 1.40.0, a seguinte função é marcada como constante ( const fn ):



Funções estáveis ​​na biblioteca padrão


As seguintes funções e macros foram estabilizadas no Rust 1.40.0:



Outras mudanças


A sintaxe , o gerenciador de pacotes de carga e o analisador Clippy também sofreram algumas alterações.


Leia as notas de compatibilidade para ver se essas alterações afetam você.


Membros 1.40.0


Muitas pessoas se uniram para criar o Rust 1.40.0. Não poderíamos ter feito isso sem todos vocês, obrigado !


De tradutores


Em caso de dúvidas sobre o idioma Rust, eles poderão ajudá-lo no bate-papo do telegrama no idioma russo ou em um bate-papo semelhante para os recém-chegados .


Este artigo foi traduzido em conjunto por andreevlex , blandger , funkill , Hippolot , P0lunin , PsyHaSTe e LooMaclin .

Source: https://habr.com/ru/post/pt481070/


All Articles