Présentation du type never
Après une décennie de travail et cinq tentatives de stabilisation, le type never (écrit !) devient officiel dans Rust 1.100. Ce type représente les calculs qui ne retournent jamais de valeur, comme les appels à return, break ou std::process::exit. La particularité du never réside dans la coercition never‑to‑any : le compilateur accepte de convertir ! en n’importe quel autre type, ce qui permet, par exemple, de faire None => return dans un match tout en conservant la cohérence de type. Le code suivant illustre ce mécanisme :
fn mrrrow(option: Option) {
let value = match option {
Some(x) => x,
None => return,
};
// ...
}
En plus, le type Infallible devient simplement un alias de !, rendant les API existantes compatibles sans rupture majeure. Une modification rétrocompatible change toutefois le « fallback » du never de () à ! pour les éditions antérieures à 2024, ce qui peut rendre certaines constructions de code plus strictes.
Stabilisation de l'API Allocator
Rust 1.100 introduit la stabilisation du trait Allocator, cœur du projet Allocators 1.0. Ce trait permet aux bibliothèques de définir des allocateurs personnalisés utilisables avec Vec et Box. La décision de stabiliser d’abord le trait central ouvre la voie à l’extension future vers d’autres collections et pointeurs. Le design repose sur une séparation claire entre l’allocation brute et la logique de conteneur, limitant ainsi les coûts d’abstraction tout en conservant les garanties de sécurité mémoire de Rust.
DropGuard : exécuter une fermeture à chaque sortie
Le nouveau type core::mem::DropGuard fournit un moyen explicite d’exécuter une fermeture lors du drop d’une variable, sans recourir au trait Drop complet. Il accepte deux arguments : la valeur à protéger et la fermeture à appeler. Le guard implémente Deref et DerefMut, ce qui laisse le code manipuler la valeur comme d’habitude. La méthode dismiss permet de récupérer la valeur sans déclencher la fermeture, facilitant la mise en place de transactions « tout‑ou‑rien ». Exemple :
use std::mem::DropGuard;
use std::num::ParseIntError;
fn parse_all(nums: &mut Vec, strings: &[&str]) -> Result<(), ParseIntError> {
let len = nums.len();
let mut nums = DropGuard::new(nums, move |nums| {
nums.truncate(len);
});
for s in strings {
nums.push(s.parse()?);
}
DropGuard::dismiss(nums);
Ok(())
}
Cette construction réduit le risque d’incohérence d’état en cas d’erreur, tout en restant compatible avec le modèle de possession de Rust.
Fonctions auxiliaires et diagnostics
La fonction std::mem::conjure_zst offre une méthode sûre (mais unsafe) pour créer des instances de types à taille nulle, remplaçant les pratiques de transmutation souvent fragiles. Elle est notamment utile pour les marqueurs comme Python<'py> de PyO3, où la création non contrôlée violerait les préconditions de sécurité. Par ailleurs, Cargo signale désormais les dépendances inutilisées grâce à un lint amélioré, limitant les faux positifs liés aux cibles multiples. Cette visibilité accrue aide les développeurs à réduire les temps de compilation et à maintenir des graphes de dépendances plus légers.