1 points par GN⁺ 4 시간 전 | 1 commentaires | Partager sur WhatsApp
  • Rust 1.96.0 peut être installé avec rustup update stable, et il est possible de participer à la validation des futures versions via les canaux beta/nightly
  • Les nouveaux types core::range::Range* implémentent IntoIterator au lieu de Iterator, ce qui permet d’implémenter Copy et en fera à terme les types par défaut de la syntaxe de plage
  • assert_matches! et debug_assert_matches! affichent aussi la représentation Debug de la valeur quand le motif ne correspond pas, ce qui facilite le diagnostic des échecs de test
  • Les cibles WebAssembly ne transmettent plus --allow-undefined par défaut, donc les symboles non définis provoquent désormais une erreur de l’éditeur de liens au lieu de devenir des imports
  • Cargo inclut des correctifs pour CVE-2026-5223 et CVE-2026-5222 destinés aux utilisateurs de registres tiers ; les utilisateurs de crates.io ne sont pas concernés

Principaux changements de Rust 1.96.0

  • Mise à jour et canaux de test

    • Les utilisateurs ayant installé Rust avec rustup peuvent obtenir Rust 1.96.0 avec rustup update stable
    • Si rustup n’est pas installé, il peut être récupéré sur la page d’installation de rustup du site de Rust, et les notes de version détaillées de la 1.96.0 sont également disponibles
    • Pour participer à la validation des futures versions, il est possible d’utiliser les canaux beta/nightly avec rustup default beta ou rustup default nightly, et les bugs peuvent être signalés sur l’issue tracker Rust
  • Nouveaux types Range*

    • Le Range existant et les types associés de core::ops étaient souvent supposés être Copy par de nombreux utilisateurs, mais ils n’implémentaient pas Copy car ils implémentent directement Iterator
    • Implémenter à la fois Iterator et Copy sur un même type est un footgun signalé par Clippy, ce qui expliquait pourquoi cette approche était évitée
    • La RFC3550 propose des types de plage alternatifs qui implémentent IntoIterator au lieu de Iterator, ce qui permet aussi à ces types d’implémenter Copy
    • La bibliothèque standard stabilise core::range::Range, core::range::RangeFrom, core::range::RangeInclusive ainsi que les itérateurs associés
    • Dans une prochaine version de Rust, core::range::RangeFull et core::range::RangeTo, réexportés depuis core::ops, seront ajoutés, tout comme core::range::legacy::*, qui deviendra le nouvel emplacement des types de plage actuels
    • La syntaxe de plage comme 0..1 crée actuellement des types legacy, mais passera aux types core::range dans une future édition
    • Grâce à cette stabilisation, il est désormais possible de stocker des accesseurs de slice dans des types Copy sans séparer start et end
    • Exemple :
      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 expose ses champs publiquement, puisqu’il n’est plus nécessaire d’éviter, comme avec la version legacy, de révéler l’état d’un itérateur épuisé
    • Comme les nouveaux types doivent d’abord être convertis avant de commencer une itération, leurs champs publics ne posent pas de problème
    • Les auteurs de bibliothèques devraient envisager d’utiliser impl RangeBounds dans leurs API publiques afin d’accepter à la fois les types de plage legacy et les nouveaux types
    • Lorsqu’un type concret est nécessaire, il est recommandé de privilégier les nouveaux types de plage, qui deviendront les types par défaut à l’avenir
  • Macros d’assertion de pattern matching

    • Les nouvelles macros assert_matches! et debug_assert_matches! vérifient qu’une valeur correspond à un motif donné et, sinon, déclenchent un panic avec la représentation Debug de cette valeur
    • Ces deux macros sont essentiellement équivalentes à assert!(matches!(..)) et debug_assert!(matches!(..)), mais la valeur affichée en cas d’échec améliore la capacité de diagnostic
    • Elles n’ont pas été ajoutées au prélude standard, car cela pourrait entrer en conflit avec des crates tierces populaires qui fournissent des macros du même nom
    • Il faut donc les importer explicitement depuis core ou std avant utilisation
    • Exemple :
      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);
      }
      
  • Changement pour les cibles WebAssembly

    • Les cibles WebAssembly ne transmettent plus --allow-undefined à l’éditeur de liens
    • Lors de l’édition de liens, les symboles non définis ne sont plus transformés en imports WebAssembly du module "env", mais provoquent une erreur de l’éditeur de liens
    • Si tous les symboles liés ne sont pas définis, le module n’est pas lié, ce qui permet de détecter les bugs plus tôt et d’éviter des problèmes accidentels liés, par exemple, aux noms de symboles
    • Des symboles liés non définis indiquent généralement un bug de build ou une erreur de configuration
    • Si l’ancien comportement était intentionnel, il peut être rétabli avec RUSTFLAGS=-Clink-arg=--allow-undefined, ou bien #[link(wasm_import_module = "env")] peut être utilisé dans le bloc qui définit les symboles dans le code source
    • Ce changement est appliqué dans Rust 1.96 à la suite d’une précédente annonce sur le blog

API stabilisées et correctifs de sécurité

1 commentaires

 
GN⁺ 4 시간 전
Avis sur Lobste.rs
  • J’ai souvent envie d’avoir assert_matches, mais à chaque fois j’hésite entre ajouter une nouvelle crate ou le réimplémenter moi-même
    Donc je suis content que ça entre dans la bibliothèque standard

    • Est-ce étrange d’avoir hâte de pouvoir supprimer des centaines de paires de parenthèses dans les tests ? Je ne pense pas du tout
  • J’aime bien l’étape qui consiste à faire des plages des types Copy
    J’ai parfois été surpris de devoir cloner une plage, et ça correspond aussi mieux à l’intuition selon laquelle 12..34 devrait être une donnée petite et copiable
    Cela dit, s’il y a plusieurs types portant le même nom, j’ai un peu peur que VS Code importe le mauvais type la prochaine fois qu’il ajoutera automatiquement une déclaration 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.
    Le système d’éditions de Rust a l’air d’être une très bonne idée

    • Si je me souviens bien, quand il y a ambiguïté dans les imports, l’action de code de VS Code doit ouvrir une liste déroulante pour choisir lequel utiliser
    • J’ai aussi l’impression qu’en temps normal, on n’aura pas souvent besoin d’importer ce genre de types
      Pour la plupart des utilisateurs, l’avantage des nouveaux types est faible, donc ils pourront simplement continuer à utiliser les types existants, et les nouveaux types seront utilisés automatiquement à la prochaine frontière d’édition
      J’imagine que ce sont surtout les auteurs de bibliothèques qui voudront prendre explicitement en charge les deux versions qui importeront ces types
  • 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.
    Ça me paraît un peu étrange
    Est-ce qu’ils comptent changer ça plus tard ? Ça ressemble au genre de chose qu’on aimerait transformer en petit nettoyage une fois que l’écosystème aura migré, par exemple au bout de 3 ans

    • C’est justement le genre de cas où les éditions aident
      On peut modifier le prélude sans casser les projets existants