Opublikowano nową wersję języka programowania ogólnego przeznaczenia Rust 1.86, który powstał w projekcie Mozilla, a obecnie jest rozwijany pod patronatem niezależnej organizacji non-profit Rust Foundation. Język koncentruje się na bezpiecznej obsłudze pamięci i dostarcza narzędzi umożliwiających osiągnięcie wysokiego poziomu równoległości wykonania zadań, przy czym nie wymaga użycia zbieracza śmieci i runtime (runtime ogranicza się do podstawowej inicjalizacji i utrzymania standardowej biblioteki).
Metody zarządzania pamięcią w Rust eliminują błędy związane z manipulowaniem wskaźnikami oraz chronią przed problemami wynikającymi z niskopoziomowej obsługi pamięci, takimi jak dostęp do pamięci po jej zwolnieniu, dereferencjonowanie wskaźników zerowych, wychodzenie poza granice bufora itp. Dla rozprowadzania bibliotek, zapewnienia budowy i zarządzania zależnościami, rozwijany jest menedżer pakietów Cargo. Dla publikacji bibliotek wspierany jest 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 wsparcie dla rzutowania (upcast) typów do bazowego supertypu (supertrait), co oznacza, że możliwe stało się bezpośrednie przekształcenie odniesienia do obiektu typu w odniesienie do obiektu supertypu bez konieczności tworzenia specjalnej metody w typie, zwracającej odniesienie do supertypu. Podobną operację można wykonać z innymi rodzajami wskaźników inteligentnych, na przykład „Arc<dyn Trait> -> Arc<dyn Supertrait>” oraz „*const dyn Trait -> *const dyn Supertrait”. trait Trait: Supertrait {} trait Supertrait {} fn upcast(x: &dyn Trait) -> &dyn Supertrait { x }
- W HashMap i na tablicach (slice) dodano metodę get_disjoint_mut() do jednoczesnego uzyskiwania kilku zmiennych odniesień do elementów. Wcześniej borrow checker nie pozwalał na jednoczesne użycie odniesień uzyskanych za pomocą metody get_mut(). let v = &mut [1, 2, 3]; if let Ok([a, b]) = v.get_disjoint_mut([0, 2]) { *a = 413; *b = 612; } assert_eq!(v, &[413, 2, 612]); if let Ok([a, b]) = v.get_disjoint_mut([0..1, 1..3]) { a[0] = 8; b[0] = 88; b[1] = 888; } assert_eq!(v, &[8, 88, 888]);
- Zezwolono na oznaczanie bezpiecznych funkcji przy użyciu atrybutu „#[target_feature]”, wskazującego, że funkcja korzysta z określonych możliwości CPU. Bezpieczną funkcję oznaczoną atrybutem „#[target_feature]” inna bezpieczna funkcja może wywołać bezpiecznie tylko pod warunkiem, że również jest oznaczona „#[target_feature]” (inaczej takie funkcje należy wywoływać w bloku unsafe). Nie można ich przekazywać do funkcji, które przyjmują parametry ogólne (generic), ograniczone typami Fn*. Wcześniej atrybut „#[target_feature]” mógł być stosowany wyłącznie w funkcjach oznaczonych jako „unsafe”. #[target_feature(enable = „avx2”)] fn requires_avx2() { // … } #[target_feature(enable = „avx2”)] fn safe_callsite() { requires_avx2(); } fn unsafe_callsite() { if is_x86_feature_detected!(„avx2”) { unsafe { requires_avx2() }; } }
- W kompilatorze Rust włączono wstawianie z zabezpieczeniami debug (debug-assert), co zapewnia, że wskaźnik nie zawiera wartości NULL podczas odczytu i zapisu niezerowych rozmiarów, a także podczas ponownego pożyczania (reborrow) wskaźnika do odniesienia. Na przykład, gdy włączone są kontrole debugowania, poniższy kod teraz wywoła stan „panic”: let _x = *std::ptr::null::(); let _x = &*std::ptr::null::();
- Domyślnie włączono kontrolę lint „missing_abi”, która generuje ostrzeżenie, jeśli po słowie kluczowym extern nie określono ABI. Wcześniej, jeśli po extern nie podano ABI, domyślnie przyjmowano ABI „C”. Teraz zaleca się wyraźne określenie ABI „C”, na przykład ‘extern „C” {}’ i ‘extern „C” fn’
- Nowa porcja API została wprowadzona do stabilnej wersji, w tym ustabilizowane metody i implementacje traitów:
- {float}::next_down
- {float}::next_up
- ::get_disjoint_mut
- ::get_disjoint_unchecked_mut
- slice::GetDisjointMutError
- HashMap::get_disjoint_mut
- HashMap::get_disjoint_unchecked_mut
- NonZero::count_ones
- Vec::pop_if
- sync::Once::wait
- sync::Once::wait_force
- sync::OnceLock::wait
- Wskaźnik „const” zastosowany w funkcjach:
- hint::black_box
- io::Cursor::get_mut
- io::Cursor::set_position
- str::is_char_boundary
- str::split_at
- str::split_at_checked
- str::split_at_mut
- str::split_at_mut_checked
- Wprowadzono trzeci poziom wsparcia dla platform {aarch64-unknown,x86_64-pc}-nto-qnx710_iosock, {aarch64-unknown,x86_64-pc}-nto-qnx800, {x86_64,i686}-win7-windows-gnu, amdgcn-amd-amdhsa, x86_64-pc-cygwin, {mips,mipsel}-mti-none-elf, m68k-unknown-none-elf, armv7a-nuttx-{eabi,eabihf}, aarch64-unknown-nuttx i thumbv7a-nuttx-{eabi,eabihf}. Trzeci poziom zakłada podstawowe wsparcie, ale bez zautomatyzowanego testowania, publikowania oficjalnych wersji i weryfikacji możliwości kompilacji kodu.
- Dodano ostrzeżenie o zakończeniu drugiego poziomu wsparcia dla docelowej platformy i586-pc-windows-msvc w następnej wersji (1.87). Zaleca się korzystanie z platformy i686-pc-windows-msvc, która różni się wsparciem dla instrukcji SSE2. Platforma i586-pc-windows-msvc straciła sens, ponieważ dla Windows 10 wymagana jest obsługa SSE2, a wcześniejsze wersje Windows w Rust nie są wspierane.
Dodatkowo warto zaznaczyć, że firma Ferrocene przekazała społeczności specyfikację języka Rust (FLS — Ferrocene Language Specification), stworzoną w procesie rozwijania własnego kompilatora Rust dla systemów krytycznych i okresowo synchronizowaną z aktualnym stanem głównego kompilatora Rust. Specyfikacja FLS zawiera uporządkowany i szczegółowy przewodnik po składni, semantyce i zachowaniu Rust, przydatny do weryfikacji, oceny zgodności i standaryzacji.
Przekazane materiały zostaną wykorzystane do stworzenia wzorcowej specyfikacji języka Rust, która będzie mogła być używana przy opracowywaniu alternatywnych kompilatorów oraz do testowania kompilatora w obszarach kluczowych z punktu widzenia bezpieczeństwa.
Źródło: opennet.ru
