1 Punkte von GN⁺ 4 시간 전 | 1 Kommentare | Auf WhatsApp teilen
  • Rust 1.96.0 kann mit rustup update stable installiert werden; an der Überprüfung künftiger Releases kann über die Beta-/Nightly-Kanäle teilgenommen werden
  • Die neuen Typen core::range::Range* implementieren IntoIterator statt Iterator, sodass sie Copy implementieren können, und sollen künftig die Standardtypen für die Bereichssyntax werden
  • assert_matches! und debug_assert_matches! geben bei einer fehlgeschlagenen Musterübereinstimmung zusätzlich die Debug-Darstellung des Werts aus und erleichtern so die Diagnose von Testfehlschlägen
  • Für WebAssembly-Targets wird --allow-undefined nicht mehr standardmäßig übergeben, sodass undefinierte Symbole nicht mehr zu Imports, sondern zu Linker-Fehlern führen
  • Cargo enthält Korrekturen für CVE-2026-5223 und CVE-2026-5222 für Nutzer von Drittanbieter-Registries; Nutzer von crates.io sind nicht betroffen

Wichtige Änderungen in Rust 1.96.0

  • Updates und Testkanäle

    • Nutzer, die Rust bereits mit rustup installiert haben, können Rust 1.96.0 mit rustup update stable erhalten
    • Falls rustup nicht vorhanden ist, kann es über die rustup-Installationsseite der Rust-Website installiert werden; außerdem ist die ausführliche 1.96.0-Release-Note veröffentlicht
    • Wer an der Validierung künftiger Releases teilnehmen möchte, kann mit rustup default beta oder rustup default nightly die Beta-/Nightly-Kanäle verwenden; Bugs können im Rust-Issue-Tracker gemeldet werden
  • Neue Range*-Typen

    • Bei den bisherigen Range- und zugehörigen core::ops-Typen erwarten viele Nutzer Copy, sie implementierten dies jedoch nicht, weil sie direkt Iterator implementieren
    • Die gleichzeitige Implementierung von Iterator und Copy für denselben Typ gilt als von Clippy beanstandete footgun und wurde daher vermieden
    • RFC3550 schlägt alternative Bereichstypen vor, die statt Iterator IntoIterator implementieren; in dieser Struktur können die betreffenden Typen auch Copy implementieren
    • In der Standardbibliothek wurden core::range::Range, core::range::RangeFrom, core::range::RangeInclusive und zugehörige Iteratoren stabilisiert
    • In einer nahen zukünftigen Rust-Version sollen außerdem core::range::RangeFull und core::range::RangeTo, die aus core::ops erneut exportiert werden, sowie core::range::legacy::* hinzukommen, das der neue Ort der aktuellen Bereichstypen wird
    • Bereichssyntax wie 0..1 erzeugt derzeit noch Legacy-Typen, soll in einer künftigen Edition aber auf core::range-Typen umgestellt werden
    • Durch die neue Stabilisierung können Slice-Indizes in Copy-Typen gespeichert werden, ohne start und end getrennt halten zu müssen
    • Beispiel:
      use core::range::Range;
      
      #[derive(Clone, Copy)]
      pub struct Span(Range<usize>);
      
      impl Span {
          pub fn of(self, s: &str) -> &str {
              &s[self.0]
          }
      }
      
    • Das neue RangeInclusive macht seine Felder öffentlich, da anders als bei der Legacy-Version kein offengelegter Zustand eines erschöpften Iterators vermieden werden muss
    • Da die neuen Typen vor dem Iterieren erst umgewandelt werden müssen, sind öffentliche Felder kein Problem
    • Autoren von Bibliotheken sollten für öffentliche APIs die Verwendung von impl RangeBounds erwägen, damit sowohl Legacy- als auch neue Bereichstypen akzeptiert werden
    • Wenn ein konkreter Typ benötigt wird, wird empfohlen, den neuen Bereichstyp zu bevorzugen, der künftig der Standard sein soll
  • Assertion-Makros für Pattern Matching

    • Die neuen Makros assert_matches! und debug_assert_matches! prüfen, ob ein Wert auf ein gegebenes Muster passt, und panicen andernfalls zusammen mit der Debug-Darstellung des betreffenden Werts
    • Beide Makros entsprechen im Wesentlichen assert!(matches!(..)) bzw. debug_assert!(matches!(..)), verbessern aber durch die Ausgabe des Werts bei einem Fehlschlag die Diagnosefähigkeit
    • Wegen möglicher Konflikte mit populären Drittanbieter-Crates, die Makros mit demselben Namen bereitstellen, wurden sie nicht dem Standard-Prelude hinzugefügt
    • Vor der Verwendung müssen sie direkt aus core oder std importiert werden
    • Beispiel:
      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);
      }
      
  • Änderungen bei WebAssembly-Targets

    • Für WebAssembly-Targets wird --allow-undefined nicht mehr an den Linker übergeben
    • Undefinierte Symbole beim Linken werden nicht mehr in WebAssembly-Imports aus dem Modul "env" umgewandelt, sondern führen zu Linker-Fehlern
    • Wenn alle linkrelevanten Symbole definiert sein müssen, wird das Modul sonst nicht gelinkt, wodurch Bugs früher erkannt und versehentliche Probleme etwa bei Symbolnamen vermieden werden können
    • Undefinierte linkrelevante Symbole deuten meist auf Bugs zur Build-Zeit oder Konfigurationsfehler hin
    • Falls das bisherige Verhalten beabsichtigt war, kann es mit RUSTFLAGS=-Clink-arg=--allow-undefined wiederhergestellt werden; alternativ kann im Quellcode #[link(wasm_import_module = "env")] in dem Block verwendet werden, der das Symbol definiert
    • Diese Änderung wird nach einer früheren Ankündigung im Blog mit Rust 1.96 wirksam

Stabilisierte APIs und Sicherheitskorrekturen

1 Kommentare

 
GN⁺ 4 시간 전
Lobste.rs-Meinungen
  • assert_matches ist etwas, das ich immer wieder haben möchte, und jedes Mal frage ich mich, ob ich dafür ein neues Crate hinzufügen oder es selbst erneut implementieren soll
    Deshalb freue ich mich, dass es in die Standardbibliothek aufgenommen wird

    • Ist es seltsam, sich darauf zu freuen, in Tests Hunderte von Klammerpaaren löschen zu können? Ich finde nicht
  • Mir gefällt der Schritt, Bereiche zu Copy-Typen zu machen
    Ich war gelegentlich überrascht, dass ich Bereiche klonen musste, und es passt auch besser zur Intuition, dass 12..34 kleine, kopierbare Daten sein sollten
    Wenn es allerdings mehrere Typen mit demselben Namen gibt, mache ich mir ein wenig Sorgen, dass VS Code beim nächsten automatischen Ergänzen einer use-Deklaration den falschen Typ importiert

    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.
    Das Edition-System von Rust scheint eine ziemlich gute Idee zu sein

    • Soweit ich weiß, sollte die Code-Aktion von VS Code bei Mehrdeutigkeiten im Import ein Dropdown-Menü öffnen, damit man auswählen kann, welches verwendet werden soll
    • Ich glaube nicht, dass man solche Typen im Alltag oft importieren muss
      Für die meisten Nutzer ist der Vorteil der neuen Typen gering, daher können sie einfach weiterhin die bestehenden Typen verwenden, und an der Grenze zur nächsten Edition werden dann automatisch die neuen Typen genutzt
      Explizit importieren werden sie vermutlich vor allem Bibliotheksautoren, die beide Versionen ausdrücklich unterstützen wollen
  • 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.
    Das fühlt sich etwas seltsam an
    Ob geplant ist, das später zu ändern? Das wirkt wie die Art von Sache, die man nach einer Umstellung des Ökosystems, sagen wir in etwa drei Jahren, als kleine Aufräumarbeit ändern möchte

    • Dabei helfen Editionen
      Man kann das Prelude ändern, ohne bestehende Projekte kaputtzumachen