Version Rust 1.40.0: # [non_exhaustive], améliorations de macro et autres améliorations

L'équipe Rust est heureuse d'annoncer la sortie d'une nouvelle version, 1.40.0. Rust est un langage de programmation qui permet à chacun de créer des logiciels fiables et efficaces.


Si vous avez installé la version précédente de Rust à l'aide de rustup , pour mettre à niveau vers la version 1.40.0, il vous suffit d'exécuter la commande suivante:


 $ rustup update stable 

Si vous n'avez pas encore installé rustup , vous pouvez l' installer à partir de la page correspondante de notre site Web, ainsi que voir les notes de version détaillées sur GitHub.


Ce qui est inclus dans la version stable 1.40.0


Les principales innovations sont l'introduction de l'attribut #[non_exhaustive] , des améliorations des macros!() Et #[attribute] . Enfin, les avertissements de l'analyseur de migration de l'emprunteur sont devenus des bogues dans Rust 2015. Voir les notes de publication pour plus d'informations.


#[non_exhaustive] structures #[non_exhaustive] , énumérations et options d'énumération


Supposons que vous êtes l'auteur d'une bibliothèque alpha contenant la pub struct Foo . Vous souhaitez rendre publics les champs de la structure alpha::Foo , mais vous ne savez pas si vous devrez ajouter d'autres champs à Foo dans les prochaines versions. Un dilemme se pose: soit vous rendez les champs privés avec des inconvénients ultérieurs, soit vous risquez de mettre les utilisateurs en dépendance des champs, puis vous violez leur code lors de l'ajout de nouveaux. Rust 1.40.0 introduit un moyen de résoudre le problème avec #[non_exhaustive] .


L'attribut #[non_exhaustive] attaché à la structure ou variante de l'énumération et empêche la comparaison complète des champs, la création de ladite structure ou variante en dehors de la caisse avec leur déclaration. L'exemple suivant montre des erreurs dans la caisse beta alpha-dépendante:


 // 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`    ... 

Que se passe-t-il dans les coulisses? La visibilité des constructeurs pour la structure #[non_exhaustive] ou l'option d'énumération sera réduite à la pub(crate) , interdisant ainsi leur utilisation dans des caisses tierces.


Un aspect peut-être plus important de #[non_exhaustive] est qu'un attribut peut être attaché aux énumérations elles-mêmes. Voici le code extrait de std::cmp::Ordering :


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

Dans ce cas, #[non_exhaustive] garantit la possibilité d'ajouter de nouvelles options à l'avenir. Ceci est réalisé en interdisant aux autres packages d'utiliser une correspondance d'image exhaustive pour la Ordering . Le compilateur rejetterait les éléments suivants:


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

Au lieu de cela, d'autres packages devraient désormais envisager la possibilité de nouvelles options d'énumération, par exemple, en ajoutant le caractère générique _ :


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

Des détails sur l'attribut #[non_exhaustive] disponibles dans le rapport de stabilisation .


Améliorations des macros et des attributs


Dans la version 1.40.0, nous avons apporté plusieurs améliorations aux macros et aux attributs, notamment:


  • mac!() dans des contextes de type.


    Par exemple, vous pouvez écrire type Foo = expand_to_type!(bar);expand_to_type sera une macro procédurale.


  • extern { ... } blocs extern { ... } .


    Ce bloc comprend les make_item!() . Par exemple:


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

    Les macros procédurales d'attribut pour les éléments des blocs extern { ... } sont désormais également prises en charge:


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

  • macro_rules! éléments dans les macros procédurales.


    Les macros avec la syntaxe de fonction ( mac!() ) Et les attributs ( #[mac] ) peuvent maintenant générer des macro_rules! . Voir le rapport de stabilisation ci-joint pour plus de détails.


  • TokenStream $m:meta prend $m:meta charge TokenStream .


    Autrement dit, le code suivant est correct:


     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 } ); 


Les avertissements de migration de l'emprunteur analyseur deviennent des bogues dans l'édition Rust 2015


Dans la version 1.35.0, nous avons signalé que NLL est apparu dans l'édition Rust 2015 après la première version de l'édition 2018 dans Rust 1.31 .


Comme nous l'avons dit, l'ancien analyseur d'emprunt pouvait permettre une gestion de la mémoire non sécurisée, et avec le nouvel analyseur (vérificateur d'emprunt NLL), ces lacunes ont été résolues. Ces erreurs pouvant perturber le code stable, nous avons décidé d'introduire progressivement ces erreurs, en vérifiant si l'ancien analyseur autoriserait l'assemblage du programme et si le nouveau le bloquerait. Dans ces cas, les erreurs ont été remplacées par des avertissements.


La version précédente de Rust 1.39.0 a remplacé ces avertissements par des erreurs de code avec l' édition 2018 . Rust 1.40.0 appliquera les mêmes modifications au code de l' édition 2015 , fermant définitivement ces trous de sécurité. Parallèlement à cela, le compilateur a même été nettoyé de l'ancien code !


Si votre projet ne va pas être dû aux changements ci-dessus, ou si vous voulez en savoir plus, lisez le post de Niko Matsakis .


Fonctions plus constantes dans la bibliothèque standard


À partir de Rust 1.40.0, la fonction suivante est marquée comme constante ( const fn ):



Fonctions stables dans la bibliothèque standard


Les fonctions et macros suivantes ont été stabilisées dans Rust 1.40.0:



Autres changements


La syntaxe , le gestionnaire de paquets de fret et l' analyseur Clippy ont également subi quelques modifications.


Veuillez lire les notes de compatibilité pour voir si ces changements vous concernent.


Membres 1.40.0


Beaucoup de gens se sont réunis pour créer Rust 1.40.0. Nous n'aurions pas pu faire cela sans vous tous, merci !


Des traducteurs


Pour toute question sur la langue rouille, ils pourront vous aider dans le chat Telegram en russe ou dans un chat similaire pour les nouveaux arrivants .


Cet article a été traduit conjointement par andreevlex , blandger , funkill , Hippolot , P0lunin , PsyHaSTe et LooMaclin .

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


All Articles