IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Rust Discussion :

Rust 1.96.0 : nouveaux types de plage, macros stabilisées et corrections de vulnérabilités dans Cargo


Sujet :

Rust

  1. #1
    Communiqués de presse

    Femme Profil pro
    Traductrice Technique
    Inscrit en
    Juin 2023
    Messages
    2 940
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Traductrice Technique

    Informations forums :
    Inscription : Juin 2023
    Messages : 2 940
    Par défaut Rust 1.96.0 : nouveaux types de plage, macros stabilisées et corrections de vulnérabilités dans Cargo
    La version 1.96.0 du langage de programmation Rust est disponible, apportant de nouveaux types Range*, de nouvelles macros stabilisées et des corrections de vulnérabilités dans Cargo

    La version 1.96.0 du langage Rust introduit de nouveaux types core::range compatibles avec Copy, permettant d'utiliser des plages dans les structs Copy et d'exposer des champs publics dans RangeInclusive. Cette version stabilise également les macros assert_matches! et debug_assert_matches!, qui améliorent les diagnostics de correspondance de motifs, bien qu'elles nécessitent une importation manuelle.

    Rust est un langage de programmation polyvalent qui met l'accent sur les performances, la sécurité des types, la concurrence et la sécurité de la mémoire. Rust prend en charge plusieurs paradigmes de programmation. Il s'inspire de concepts issus de la programmation fonctionnelle, notamment l'immuabilité, les fonctions d'ordre supérieur, les types de données algébriques et la correspondance de motifs. Il prend également en charge la programmation orientée objet via des structures, des énumérations, des traits et des méthodes. Rust garantit la sécurité de la mémoire (c'est-à-dire que toutes les références pointent vers une mémoire valide) sans recourir à un ramasse-miettes classique ; à la place, les erreurs de sécurité de la mémoire et les conflits d'accès sont évités par le « vérificateur d'emprunt », qui suit la durée de vie des objets référencés lors de la compilation.

    La version 1.96.0 du langage Rust introduit de nouveaux types core::range compatibles avec Copy, permettant d'utiliser des plages dans les structs Copy et d'exposer des champs publics dans RangeInclusive. Cette version stabilise également les macros assert_matches! et debug_assert_matches!, qui améliorent les diagnostics de correspondance de motifs, bien qu'elles nécessitent une importation manuelle. Les cibles WebAssembly traitent désormais les symboles de l'éditeur de liens non définis comme des erreurs par défaut. Deux vulnérabilités de Cargo affectant les registres tiers sont également corrigées.

    Nom : 1.jpg
Affichages : 354
Taille : 18,4 Ko

    Voici les nouveautés de la version stable 1.96.0 :

    Nouveaux types Range*.

    De nombreux utilisateurs s'attendent à ce que Range et les types core::ops associés soient de type Copy, mais ce n'est pas le cas : ils implémentent directement Iterator, et il serait risqué d'implémenter à la fois Iterator et Copy sur le même type, ce qui a donc été évité. La RFC3550 proposait un ensemble de types Range de remplacement qui implémentent IntoIterator plutôt qu'Iterator, ce qui signifie qu'ils peuvent également être de type Copy. La partie de cette RFC concernant la bibliothèque standard est désormais stable, introduisant :

    - core::range::Range,
    - core::range::RangeFrom,
    - core::range::RangeInclusive.
    - Itérateurs associés

    Une version de Rust à venir ajoutera également core::range::RangeFull et core::range::RangeTo en tant que réexportations depuis core::ops (ces derniers n'implémentent pas Iterator et implémentent déjà Copy), ainsi que core::range::legacy::* en tant que nouvel emplacement pour les plages actuelles. La syntaxe de plage telle que 0..1 produit encore les types hérités pour l'instant, mais sera mise à jour vers les types core::range dans une future édition.

    Grâce à ces stabilisations, il est désormais possible de stocker des accesseurs de tranche dans des types Copy sans séparer start et end :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    use core::range::Range;
     
    #[derive(Clone, Copy)]
    pub struct Span(Range<usize>);
     
    impl Span {
        pub fn of(self, s: &str) -> &str {
            &s[self.0]
        }
    }


    Le nouveau RangeInclusive rend également ses champs publics, contrairement à l'ancienne version qui évitait d'exposer l'état d'itérateur épuisé. Cela ne pose pas de problème avec le nouveau type, car celui-ci doit être converti pour pouvoir commencer l'itération.

    Les auteurs de bibliothèques devraient envisager d'utiliser impl RangeBounds dans leur API publique, qui accepte à la fois les anciens types de plage et les nouveaux. Si un type concret est nécessaire, privilégiez l'utilisation des nouvelles plages, car celles-ci finiront par devenir la norme.

    Assertions de correspondance de motifs

    Les nouvelles macros assert_matches! et debug_assert_matches! vérifient qu’une valeur correspond à un motif donné, et déclenchent une panique avec une représentation Debug de la valeur dans le cas contraire. Elles sont essentiellement identiques à assert!(matches!(..)) et debug_assert!(matches!(..)), mais la valeur affichée améliore les chances de diagnostiquer l’échec.

    Ces nouvelles macros n’ont pas été ajoutées au prélude standard, car elles entreraient en conflit avec des crates tierces populaires fournissant des macros du même nom. Elles doivent donc être importées manuellement depuis core ou std avant utilisation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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);
    }


    Modifications apportées aux cibles WebAssembly

    Les cibles WebAssembly ne transmettent plus l'option --allow-undefined à l'éditeur de liens, ce qui signifie que les symboles non définis lors de la liaison génèrent désormais une erreur d'éditeur de liens au lieu d'être convertis en importations WebAssembly à partir du module "env". Cette modification empêche la liaison des modules tant que tous les symboles liés à la liaison ne sont pas définis, afin de détecter les bogues plus tôt et d'éviter les problèmes accidentels liés à la dénomination des symboles ou autres.

    Les symboles liés à la liaison non définis sont souvent le signe de bogues liés à la compilation ou d’une mauvaise configuration. Si, toutefois, l’ancien comportement est souhaité, il peut être réactivé avec RUSTFLAGS=-Clink-arg=--allow-undefined ou en modifiant le code source et en utilisant #[link(wasm_import_module = « env »)] sur le bloc définissant le symbole.

    Ce changement avait été annoncé précédemment et prend désormais effet dans Rust 1.96.

    Deux avis de sécurité concernant Cargo

    Rust 1.96 contient des correctifs pour deux vulnérabilités affectant les utilisateurs de registres tiers.

    - CVE-2026-5223 est une vulnérabilité de gravité moyenne concernant l'extraction d'archives de crates contenant des liens symboliques.
    - CVE-2026-5222 est une vulnérabilité de gravité faible concernant l'authentification avec des URL normalisées.

    Les utilisateurs de crates.io ne sont affectés par aucune de ces vulnérabilités.

    Source : Annonce de Rust 1.96.0

    Et vous ?

    Pensez-vous que cette version est crédible ou pertinente ?
    Quel est votre avis sur le sujet ?

    Voir aussi :

    Rust a-t-il atteint son plafond de popularité ? Le langage recule de trois places dans l'index TIOBE d'avril 2026. Son PDG évoque une « courbe d'apprentissage difficile pour les développeurs non experts »

    Submergé par les bugs dans ses applications, la solution de Microsoft c'est de supprimer tout le code C et C++ de ses référentiels d'ici 2030, pour le remplacer par Rust

    « Rust sauvera Linux de l'IA », affirme Greg Kroah-Hartman dans le cadre d'une critique de l'usage de l'intelligence artificielle pour trouver les bogues au sein du code du noyau écrit en langage C
    Publication de communiqués de presse en informatique. Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2015
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2015
    Messages : 676
    Par défaut Mmmm...
    à toutes et tous, et à Uther

    Je vois que Rust introduit le type "Range", c'est exactement (si j'ai bien compris l'article), la même idée que j'ai eue pour mon petit langage Home.
    J'ai déjà introduit cela dans le code et dans la génération de l'IRC. Là je suis en train de voir comment passer ces ranges à une fonction, j'ai pas encore la solution complète, mais je sens bien que j'y arrive tout doucement... C'est une très bonne idée de l'équipe Rust, et moi ça me donne confiance dans le développement de mon langage et de sont compilateur de lire ce genre de news

    BàV et Peace & Love

  3. #3
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 150
    Par défaut
    Citation Envoyé par OuftiBoy Voir le message
    Je vois que Rust introduit le type "Range", c'est exactement (si j'ai bien compris l'article),
    Bonjour OuftiBoy!

    Les ranges existent depuis longtemps. Déjà présent dans la version 1.0 de 2015.

    Là il s'agit d'une version alternative qui permet la copie. On dirait que ces versions remplaceront les anciennes pour certaines fonctionnalités, mais quoiqu'il en soit, ces nouveaux range ne sont pas des itérateurs, mais peuvent être transformés en itérateurs (la différence entre implémenter le trait 'Iterator' ou implémenter le trait 'IntoIterator').

    Et bon courage pour ton langage.

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2015
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2015
    Messages : 676
    Par défaut
    fdecode,

    Citation Envoyé par fdecode Voir le message
    Les ranges existent depuis longtemps. Déjà présent dans la version 1.0 de 2015.

    Là il s'agit d'une version alternative qui permet la copie. On dirait que ces versions remplaceront les anciennes pour certaines fonctionnalités, mais quoiqu'il en soit, ces nouveaux range ne sont pas des itérateurs, mais peuvent être transformés en itérateurs (la différence entre implémenter le trait 'Iterator' ou implémenter le trait 'IntoIterator').
    Je n'avais pas vu cela, je m'étais attardé plus sur la protection mémoire. Mais a y regarder de plus près, ce que je fais est plus "basic". Mes "ranges" permettent de ne jamais pouvoir déborder d'un tableau (à la compilation), et d'éviter des type 'underflow' ou 'overflow' (à la compilation). Le compilateur 'trace' chaque utilisation des variables, quelle qu'elles soient, et émet une erreur si un 'risque' existe. Pour que la vérification se fasse dès compilation, le compilateur 'connait' ce que l'on peut encore 'retirer' ou 'ajouter' à une variable. C'est très précis avec des constantes, et un peut moins si ne connait que le max d'une variable. C'est pour ça que je n'utilise pas les 'types machine', remplacés par mes 'ranges' dont on peut définir la plage très précisément.

    Lors de la génération de l'IRC j'utilise évidemment des 'types' machine, mais le compilateur a valider les 'bornes' de chaque variable avant.

    Citation Envoyé par fdecode Voir le message
    Et bon courage pour ton langage.


    J'avance bien, j'alterne entre faire avancer le compilateur, le langage, et la doc (qui prend vite du temps).

    BàT et Peace & Love.

  5. #5
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 773
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 773
    Par défaut
    En effet la notion de range dans ton langage, de ce que j'en est compris est plus proche des range d'Ada : une limitation définie à la compilation des valeurs possible sur un type.
    Les range en Rust sont juste des types normaux (struct) qui représentant un intervalle. mais sans grand chose de particulier à part une écriture abrégée.

  6. #6
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 150
    Par défaut
    Citation Envoyé par Uther Voir le message
    En effet la notion de range dans ton langage, de ce que j'en est compris est plus proche des range d'Ada : une limitation définie à la compilation des valeurs possible sur un type.
    Les range en Rust sont juste des types normaux (struct) qui représentant un intervalle. mais sans grand chose de particulier à part une écriture abrégée.
    On peut faire des ranged type maison en Rust [playground]:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #[repr(transparent)]
    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct RangedI128<const MIN: i128, const MAX: i128>(i128);
     
    impl<const MIN: i128, const MAX: i128> RangedI128<MIN, MAX> {
        const _ASSERT_BOUNDS: () = assert!(MAX >= MIN);
     
        pub const fn try_new(x: i128) -> Option<Self> {
            let _ = Self::_ASSERT_BOUNDS;
            if x < MIN || x > MAX {
                None
            } else {
                Some(Self(x))
            }
        }
     
        pub const fn get(self) -> i128 {
            self.0
        }
    }
    Ça pourrait être un peu mieux, mais on est limité par les capacités actuelles des génériques constants.

  7. #7
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 773
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 773
    Par défaut
    En effet j'avais fait quelques essais de type entier bornés par des const génériques, mais on finit vite par tomber sur des limites, y compris en activant certaines parties encore expérimentales du support des const génériques.

  8. #8
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 150
    Par défaut
    Citation Envoyé par Uther Voir le message
    En effet j'avais fait quelques essais, mais on finit vite par tomber sur des limites, y compris en activant certaines parties encore expérimentales du support des const génériques.
    Par exemple, il n'y a pas d'arithmétique sur les const génériques en stable pour l'instant.

    Ceci étant dit, le crate typenum:
    https://crates.io/crates/typenum/
    est une jolie application des capacités des traits Rust pour définir des types à signification numérique (et en binaire).
    Un exemple [playground]:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    use std::ops::{ Mul, Sub};
     
    #[macro_use] extern crate typenum;
    use typenum::{ Unsigned, Integer, Sub1, Prod, Bit, UInt, consts::* };
     
    // deux calculs de type numérique
    type X0 = op!(pow(P3,P4) + P3 * (P2 - N2));
    type X1 = op!(P1 + P2 * (P2 - N2));
     
    type Result0 = op!(P93 == X0);
    type Result1 = op!(P8 == X1);
     
    /// Calcul statique de la factoriel d'un type numérique non signé
    trait Factorial {
        type F;
    }
    /// Shortcut
    type Fact<U> = <U as Factorial>::F;
    // initialisation
    impl Factorial for U0 {
        type F = U1;
    }
    // récursion
    impl<U: Unsigned, B: Bit> Factorial for UInt<U, B> where UInt<U, B>: Sub<B1>, 
           Sub1<UInt<U, B>>: Factorial, UInt<U, B> : Mul< Fact<Sub1<UInt<U, B>>> > {
        type F = Prod<UInt<U, B>, Fact<Sub1<UInt<U, B>>> >;
    }
     
    /// Factorielle de 20
    type F20 = Fact<U20>;
     
    fn main() {
        println!("X0 -> {}", X0::to_i64());
        println!("X1 -> {}", X1::to_i64());
        println!("Result0 -> {}", Result0::to_bool());
        println!("Result1 -> {}", Result1::to_bool());
        println!("20! = {}\n", F20::to_i64());
    }
    Bien entendu, cet exemple d'implémentation de la factorielle en typenum est plus complexe qu'un calcul de factorielle par template en C++.
    Mais il faut noter que l'arithmétique des constantes génériques n'est pas stabilisée en Rust pour l'instant.
    Il s'agit d'une méthode de contournement, qu'autorise le système de typage de Rust. Et les arcanes des traits et du conditionnement de types requièrent une certaine expérience.

    Mais c'est grâce à typenum que, par exemple, nalgebra peut implémenter du calcul matriciel avec contrôle de compatibilité dimensionnelle au niveau du typage (pour les matrices de shape statique).

    Quand on débute en Rust on comprend vite que le langage est bas niveau et est sécurisé en mémoire, mais on n'imagine pas forcément ce que permet son système de type.

  9. #9
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 773
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 773
    Par défaut
    Typenum, c'est quand même un hack du système de type. C'est peut-être acceptable pour des petites valeurs comme le nombre de dimensions, mais pour les types numérique qu'on utilise partout, c'est vraiment trop de bricolage.

  10. #10
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 150
    Par défaut
    Citation Envoyé par Uther Voir le message
    Typenum, c'est quand même un hack du système de type. C'est peut-être acceptable pour des petites valeurs comme le nombre de dimensions
    C'est un hack, oui. Mais c'est un hack binaire: le type U20 est obtenu par un assemblage de types B0 et B1.
    Donc on a une complexité qui est réduite logarithmiquement par le codage binaire.

    Dans cet exemple, tu vois bien que le type F20 que j'ai défini (factorielle de 20) est un entier plutôt grand.

    Mais je suis d'accord, cela ne remplacera pas une véritable arithmétique des génériques constants. C'est une belle performance de codage par contre, je trouve.

    Citation Envoyé par Uther Voir le message
    pour les types numérique qu'on utilise partout, c'est vraiment trop de bricolage.
    C'est propre et ça marche plutôt bien.

  11. #11
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 773
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 773
    Par défaut
    Je suis d'accord que c'est un très belle performance, mais je ne conseillerais pas ça pour quelque chose d'aussi central que le remplacement des types numériques de base, a moins d'avoir un besoin très fort sur ce sujet.
    • Ca ajoute un style de codage supplémentaire
    • Ca a probablement un impact substantiel sur les performances de compilation. Même si l'impact de la taille des nombre est logarithmique, le moindre nombre traité va nécessiter la combinaison de plusieurs types.
    • Ca a aussi un impact sur la lisibilité des messages d'erreur, si je me souviens bien (la dernière fois que j'ai joué avec typenum date un peu.)

  12. #12
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 150
    Par défaut
    Citation Envoyé par Uther Voir le message
    je ne conseillerais pas ça pour quelque chose d'aussi central que le remplacement des types numériques de base, a moins d'avoir un besoin très fort sur ce sujet.
    Bien entendu!

Discussions similaires

  1. Problème d'ajout de nouveaux types de documents
    Par lodacom dans le forum Alfresco
    Réponses: 3
    Dernier message: 28/02/2011, 17h37
  2. [Toutes versions] Etat et critères de type "In (Plage, de, valeur)"
    Par Luc1an0 dans le forum IHM
    Réponses: 3
    Dernier message: 10/09/2009, 17h11
  3. Nouveaux types de GETTER and SETTER
    Par diabli73 dans le forum C#
    Réponses: 5
    Dernier message: 28/07/2009, 11h27
  4. [Base de Registre] Nouveaux type de valeur !?
    Par Lung dans le forum Langage
    Réponses: 4
    Dernier message: 07/04/2004, 10h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo