È stata pubblicata la versione 1.96 del linguaggio di programmazione Rust, originariamente sviluppato da Mozilla e ora mantenuto da un'organizzazione indipendente senza scopo di lucro, la Rust Foundation. Il linguaggio è incentrato sulla gestione sicura della memoria e fornisce strumenti per raggiungere un alto livello di parallelismo nell'esecuzione delle attività, evitando al contempo la necessità di un garbage collector e di un runtime (il runtime è limitato a una semplice inizializzazione e alla gestione della libreria standard).
I metodi di gestione della memoria in Rust mirano a eliminare gli errori durante la manipolazione dei puntatori e a proteggere da problemi derivanti da operazioni a basso livello sulla memoria, come l'accesso a memoria già liberata, la dereferenziazione di puntatori nulli e il superamento dei limiti del buffer, ecc. Per la distribuzione delle librerie, la gestione della compilazione e delle dipendenze, il progetto ha sviluppato un gestore di pacchetti chiamato Cargo. Per la pubblicazione delle librerie è disponibile un repository chiamato crates.io.
La gestione sicura della memoria in Rust è garantita durante la compilazione tramite il controllo dei riferimenti, il tracciamento della proprietà degli oggetti, la gestione della durata degli oggetti (scope) e la valutazione della correttezza dell'accesso alla memoria durante l'esecuzione del codice. Rust offre anche strumenti per proteggere da overflow interi, richiede l'inizializzazione obbligatoria dei valori delle variabili prima dell'uso, gestisce meglio gli errori nella libreria standard, applica il concetto di riferimenti e variabili immutabili per impostazione predefinita e offre una forte tipizzazione statica per ridurre al minimo gli errori logici.
Novità principali:
- È stato aggiunto il modulo range con l'implementazione di nuovi tipi, in fase di sviluppo per sostituire i tipi obsoleti Range, RangeInclusive, RangeToInclusive e RangeFrom, che consentono di archiviare intervalli in strutture Copy. Il tipo Range definisce intervalli limitati dal valore minimo e massimo consentito (escludendoli), il tipo RangeFrom definisce numeri a partire dal valore specificato, mentre il tipo RangeInclusive rappresenta i valori dell'intervallo specificato comprensivo di entrambi i suoi limiti. Nelle future versioni verranno introdotti anche i tipi RangeFull e RangeTo; l'implementazione precedente sarà trasferita in core::range::legacy::*, e la sintassi «N..M» sarà convertita nel nuovo tipo.
I nuovi tipi si differenziano in quanto invece di implementare il tratto Iterator, implementano il tratto IntoIterator, ossia definiscono come trasformare un tipo in un iteratore invece di utilizzare l'iteratore incorporato. Questo approccio consente di utilizzare l'operazione di copia con i nuovi tipi (il tratto Copy, che indica che i valori di quel tipo possono essere duplicati tramite una copia semplice), operazione che in precedenza non era disponibile a causa dell'incompatibilità con i tipi dotati di iteratori incorporati.
Ad esempio, i nuovi tipi consentono di mantenere i confini della sezione in una struttura che viene completamente copiata senza memorizzare separatamente i valori iniziali e finali:use core::range::Range;
#[derive(Clone, Copy)]
pub struct Span(Range);impl Span {
pub fn of(self, s: &str) -> &str {
&s[self.0]
}
} - Sono stati aggiunti i macro "assert_matches!" e "debug_assert_matches!", che verificano la corrispondenza di un valore con uno schema specificato e terminano con errore in caso di discrepanza. Rispetto alle espressioni "assert!(matches!(..))" e "debug_assert!(matches!(..))", i nuovi macro si differenziano per la visualizzazione delle informazioni di debug con i valori che hanno provocato il fallimento. Per evitare sovrapposizioni con i macro di terze parti forniti con nomi simili, i nuovi macro richiedono un'importazione esplicita della libreria "core::assert_matches."
use core::assert_matches;
fn get_random_number() -> u32 {
4
}fn main() {
assert_matches!(get_random_number(), 1..=6);
} - Durante la compilazione per la piattaforma WebAssembly, è stata interrotta la trasmissione dell'opzione di collegamento «—allow-undefined», che consentiva il collegamento in presenza di simboli indefiniti, i quali venivano convertiti in importazione dal modulo «env». Nella compilazione per WebAssembly, tutti i simboli collegati devono ora essere obbligatoriamente definiti. Per ripristinare il comportamento precedente, è possibile utilizzare la variabile di ambiente «RUSTFLAGS=-Clink-arg=—allow-undefined» o l'espressione ‘#[link(wasm_import_module = «env»)]’ nel codice.
- Una nuova serie di API è stata traslata nella categoria stabile, stabilizzando i metodi e le implementazioni dei tipi:
- assert_matches!
- debug_assert_matches!
- From per AssertUnwindSafe
- From per LazyCell
- From per LazyLock
- core::range::RangeToInclusive
- core::range::RangeToInclusiveIter
- core::range::RangeFrom
- core::range::RangeFromIter
- core::range::Range
- core::range::RangeIter
- Nel gestore di pacchetti Cargo è stata risolta una vulnerabilità CVE-2026-5223, che può essere sfruttata per sovrascrivere il codice sorgente di un altro pacchetto crate nella cache locale dei pacchetti dallo stesso repository tramite manipolazioni dei collegamenti simbolici all'interno del crate. La vulnerabilità si manifesta solo durante l'utilizzo di repository di pacchetti di terze parti e non colpisce gli utenti del repository crates.io, poiché su crates.io è vietato caricare pacchetti con collegamenti simbolici.
In aggiunta, si segnala la pubblicazione (PDF) dei risultati dell'analisi dell'idoneità del linguaggio Rust per lo sviluppo di firmware per microcontrollori e sistemi embedded con risorse limitate.
Lo studio è stato condotto da STMicroelectronics con la partecipazione di diverse università europee. A due squadre di sviluppatori isolate è stato assegnato il compito di implementare lo stesso firmware per i microcontrollori STM32U585AI con core Arm Cortex-M33. La prima squadra ha sviluppato il firmware in C, mentre la seconda in Rust.
I testato del lavoro eseguito non ha mostrato vantaggi significativi nell'utilizzo del linguaggio C rispetto a Rust nello sviluppo di firmware per microcontrollori, considerando il consumo di memoria e le prestazioni. Inoltre, l'uso del runtime di sistema scritto in Rust del progetto open source Ariel OS ha consentito di ottenere un consumo di memoria nel progetto Rust inferiore a quello dell'implementazione in C, che utilizza un tradizionale stack per lo sviluppo di firmware basato sulla libreria newlib.
La dimensione del firmware risultante è stata di 84100 byte nel progetto Rust e 76744 byte nel progetto C (il 10% in meno), ma il consumo di memoria nel firmware Rust è risultato significativamente inferiore — 24640 byte contro 42608 byte. Per quanto riguarda le prestazioni, nei test dei prototipi iniziali, sviluppati in 6 settimane, l'implementazione in Rust ha superato quella in C di due volte, ma entrambe le implementazioni erano significativamente al di sotto della massima prestazione teorica. Dopo 4 settimane dedicate all'ottimizzazione, entrambe le implementazioni hanno raggiunto risultati simili, vicini al massimo teorico previsto.

Fonte: opennet.ru
