Opublikowano wydanie języka programowania Rust 1.96, który został stworzony przez projekt Mozilla, a obecnie jest rozwijany pod egidą niezależnej organizacji non-profit Rust Foundation. Język koncentruje się na bezpiecznym zarządzaniu pamięcią i oferuje środki do osiągania wysokiego poziomu równoległości w realizacji zadań, przy tym omijając użycie zbieracza śmieci oraz runtime (które ogranicza się do podstawowej inicjalizacji oraz wsparcia standardowej biblioteki).
Metody zarządzania pamięcią w Rust mają na celu eliminację błędów przy manipulacji wskaźnikami oraz ochronę przed problemami wynikającymi z niskopoziomowego zarządzania pamięcią, takimi jak dostęp do pamięci po jej zwolnieniu, dereferencjonowanie wskaźników zerowych, czy przekroczenie granic bufora itd. Aby ułatwić dystrybucję bibliotek, budowanie oraz zarządzanie zależnościami, projekt rozwija menedżer pakietów Cargo. Wsparcie dla repozytoriów bibliotek zapewnia repozytorium crates.io.
Bezpieczne zarządzanie pamięcią w Rust jest zapewnione podczas kompilacji poprzez kontrolę referencji, śledzenie własności obiektów, uwzględnianie czasu życia obiektów (zakresu widoczności) oraz ocenę prawidłowości dostępu do pamięci w czasie wykonywania kodu. Rust oferuje również narzędzia do ochrony przed przepełnieniami liczbowymi, wymaga obowiązkowej inicjalizacji wartości zmiennych przed użyciem, lepiej obsługuje błędy w standardowej bibliotece, stosuje koncepcję niemutowalności (immutable) referencji i zmiennych domyślnie oraz oferuje silne statyczne typowanie w celu minimalizacji błędów logicznych.
Główne nowości:
- Dodano moduł range z implementacją nowych typów, które mają na celu zastąpienie przestarzałych typów Range, RangeInclusive, RangeToInclusive i RangeFrom, a także umożliwiają przechowywanie zakresów w strukturach typu Copy. Typ Range definiuje zakresy ograniczone minimalną i maksymalną dozwoloną wartością (nie włączając ich), typ RangeFrom definiuje liczby zaczynające się od określonej wartości, natomiast typ RangeInclusive — wartości określonego zakresu wraz z oboma jego granicami. W przyszłych wydaniach pojawią się dodatkowe typy RangeFull i RangeTo, a stara implementacja zostanie przeniesiona do core::range::legacy::*, a składnia „N..M” zostanie dostosowana do nowego wariantu typów.
Nowe typy różnią się tym, że zamiast cech Iterator implementują cechę IntoIterator, tzn. zamiast wbudowanego iteratora definiują sposób przekształcania typu w iterator. Tego rodzaju podejście pozwala na stosowanie operacji kopiowania z nowymi typami (cecha Copy, pokazująca, że wartości typu można duplikować poprzez proste kopiowanie), która wcześniej była niedostępna z powodu niekompatybilności z typami posiadającymi wbudowane iteratory.
Na przykład, nowe typy umożliwiają zapisanie granic wycinka w strukturze, która jest całkowicie kopiowana bez oddzielnego przechowywania wartości początkowej i końcowej:use core::range::Range;
#[derive(Clone, Copy)]
pub struct Span(Range);impl Span {
pub fn of(self, s: &str) -> &str {
&s[self.0]
}
} - Dodano makra „assert_matches!” i „debug_assert_matches!”, które sprawdzają zgodność wartości z podanym wzorcem i kończą wykonanie w przypadku niespójności. W przeciwieństwie do wyrażeń „assert!(matches!(..))” oraz „debug_assert!(matches!(..))”, nowe makra różnią się wyjściem informacji debugujących z wartościami, które spowodowały błąd. Aby uniknąć kolizji z zewnętrznymi makrami dostarczanymi w podobnych nazwach, nowe makra wymagają jawnego importu biblioteki „core::assert_matches.”
use core::assert_matches;
fn get_random_number() -> u32 {
4
}fn main() {
assert_matches!(get_random_number(), 1..=6);
} - Podczas kompilacji dla docelowej platformy WebAssembly wstrzymano przekazywanie do linkera opcji „—allow-undefined”, która umożliwiała łączenie przy obecności niezdefiniowanych symboli, które zostały przekształcone w import z modułu „env”. Przy kompilacji dla WebAssembly wszystkie symbole związane z linkowaniem muszą być teraz domyślnie zdefiniowane. Aby przywrócić wcześniejsze zachowanie, można użyć zmiennej środowiskowej „RUSTFLAGS=-Clink-arg=—allow-undefined” lub wyrażenia ‘#[link(wasm_import_module = „env”)]’ w kodzie.
- Nowa porcja API została wprowadzona do stabilnej wersji, w tym ustabilizowane metody i implementacje traitów:
- assert_matches!
- debug_assert_matches!
- From dla AssertUnwindSafe
- From dla LazyCell
- From dla LazyLock
- core::range::RangeToInclusive
- core::range::RangeToInclusiveIter
- core::range::RangeFrom
- core::range::RangeFromIter
- core::range::Range
- core::range::RangeIter
- W menedżerze pakietów Cargo usunięto lukę CVE-2026-5223, która może być użyta do nadpisania kodu źródłowego innego pakietu crate w lokalnej pamięci podręcznej pakietów z tego samego repozytorium poprzez manipulację symlinkami wewnątrz crate’a pakietów. Luka objawia się tylko podczas pracy z zewnętrznymi repozytoriami pakietów i nie dotyczy użytkowników repozytorium crates.io, ponieważ w crates.io zabrania się przesyłania pakietów z symlinkami.
Dodatkowo można wspomnieć o publikacji (PDF) wyników analizy przydatności języka Rust do tworzenia firmware’u dla mikrokontrolerów i systemów wbudowanych o ograniczonych zasobach.
Badanie przeprowadzono przez firmę STMicroelectronics we współpracy z kilkoma europejskimi uniwersytetami. Dwa izolowane zespoły programistów otrzymały zadanie zaimplementowania tego samego firmware’u dla mikrokontrolerów STM32U585AI z rdzeniem Arm Cortex-M33. Pierwszy zespół tworzył firmware w C, a drugi w Rust.
Testowanie zrealizowanej pracy nie wykazało zauważalnych korzyści z użycia języka C zamiast Rust przy tworzeniu firmware’u dla mikrokontrolerów w porównaniu pod względem zużycia pamięci i wydajności. Co więcej, wykorzystanie napisanego w Rust systemowego runtime od otwartego projektu Ariel OS pozwoliło uzyskać mniejsze zużycie pamięci w projekcie opartym na Rust niż w realizacji w języku C, korzystającej z tradycyjnego stosu do tworzenia firmware’u opartego na bibliotece newlib.
Rozmiar wynikowego oprogramowania układowego wyniósł 84100 bajtów w projekcie napisanym w Rust i 76744 bajty w projekcie w C (o 10% mniej), ale zużycie pamięci RAM w oprogramowaniu układowym napisanym w Rust było znacznie niższe — 24640 bajtów w porównaniu do 42608 bajtów. Jeśli chodzi o wydajność, podczas testowania wstępnych prototypów, opracowanych w ciągu 6 tygodni, realizacja w Rust wyprzedzała realizację w C o dwa razy, ale obie realizacje znacznie odstawały od obliczonej maksymalnej wydajności. Po 4 tygodniach poświęconych na optymalizację, obie realizacje osiągnęły w przybliżeniu ten sam wynik, zbliżony do obliczonego maksimum.

Źródło: opennet.ru
