Restrictions assouplies lors de la mise en œuvre des traits
Pour éviter les ruptures dans l'écosystème lorsqu'une dépendance ajoute un nouveau trait implicite, Rust applique la règle orpheline. L'essentiel est qu'un imp de trait n'est autorisé que si le trait ou le type mis en œuvre est local (défini dans) au crate actuel par opposition à un crate étranger. Ce que cela signifie exactement est cependant compliqué lorsque des génériques sont impliqués.
Avant Rust 1.41.0, la règle des orphelins était inutilement stricte, gênant la composition. Par exemple, supposons que votre crate définisse la structure BetterVec<T> et que vous souhaitiez un moyen de convertir votre structure en Vec<T> de la bibliothèque standard. Le code que vous écririez est:
Code Rust : | Sélectionner tout |
1 2 3 | impl<T> From<BetterVec<T>> for Vec<T> { // ... } |
... qui est une instance du modèle:
Code Rust : | Sélectionner tout |
1 2 3 | impl<T> ForeignTrait<LocalType> for ForeignType<T> { // ... } |
Dans Rust 1.40.0, cet imp était interdit par la règle des orphelins, car From et Vec sont définis dans la bibliothèque standard, qui est étrangère au crate actuel. Il y avait des façons de contourner la limitation, comme le modèle de nouveau type, mais elles étaient souvent lourdes, voire impossibles dans certains cas.
Bien qu'il soit toujours vrai que From et Vec sont étrangers, le trait (dans ce cas, From) a été paramétré par un type local. Par conséquent, Rust 1.41.0 autorise cet imp :
cargo installmet à jour les packages lorsqu'ils sont obsolètes
Avec cargo install, vous pouvez installer des crates binaires dans votre système. La commande est souvent utilisée par la communauté pour installer des outils CLI populaires écrits en Rust.
À partir de Rust 1.41.0, cargo install mettra également à jour les installations existantes de crate si une nouvelle version est sortie depuis que vous l'avez installée. Avant cette version, la seule option était de passer l'indicateur --force, qui réinstalle le crate binaire même si elle est à jour.
Un format cargo.lock moins sujet aux conflits
Pour garantir des builds cohérents, Cargo utilise un fichier nommé Cargo.lock, contenant les versions de dépendance et les sommes de contrôle. Malheureusement, la façon dont les données étaient organisées a entraîné des conflits de fusion inutiles lors du changement de dépendances dans des branches distinctes.
Rust 1.41.0 introduit un nouveau format pour le fichier, explicitement conçu pour éviter ces conflits. Ce nouveau format sera utilisé pour tous les nouveaux fichiers de verrouillage, tandis que les fichiers de verrouillage existants reposeront toujours sur le format précédent.
Plus de garanties lors de l'utilisation de Box <T> dans FFI
À partir de Rust 1.41.0, une Box<T>, où T: Sized est désormais compatible ABI avec les types de pointeur (T *) du langage C. Donc, si vous avez une fonction Rust "C" externe, appelée depuis C, votre fonction Rust peut maintenant utiliser Box<T>, pour certains T spécifiques, tout en utilisant T * dans C pour la fonction correspondante. Par exemple, du côté C, vous pouvez avoir:
Code C : | Sélectionner tout |
1 2 3 4 5 6 7 | // C header */ // Returns ownership to the caller. struct Foo* foo_new(void); // Takes ownership from the caller; no-op when invoked with NULL. void foo_delete(struct Foo*); |
... alors que du côté Rust, vous auriez:
Code Rust : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | #[repr(C)] pub struct Foo; #[no_mangle] pub extern "C" fn foo_new() -> Box<Foo> { Box::new(Foo) } // The possibility of NULL is represented with the `Option<_>`. #[no_mangle] pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {} |
Changement dans la bibliothèque
Les ajouts suivants ont été faits à la bibliothèque standard :
Les méthodes Result::map_or et Result::map_or_else ont été stabilisées. Comme Option::map_or et Option::map_or_else, ces méthodes sont des raccourcis vers le modèle .map(|val| process(val)).unwrap_or(default).
Les valeurs numériques NonZero* implémentent désormais From<NonZero*> s'il s'agit d'une plus petite largeur entière. Par exemple, NonZeroU16 implémente désormais From<NonZeroU8>.
Les méthodes weak_count et strong_count sur les pointeurs Weak ont été stabilisées :
- std::rc::Weak::weak_count
- std::rc::Weak::strong_count
- std::sync::Weak::weak_count
- std::sync::Weak::strong_count
Ces méthodes retournent le nombre de pointeurs weak (rc::Weak<T> et sync::Weak<T>) ou strong (Rc<T> et Arc<T>) pointers respectivement à leur allocation.
MaybeUninit<T> implémente désormais fmt::Debug.
Source : Rust