IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Rust 1.65 est disponible, elle apporte les types génériques associés stables,
Ils permettent d'avoir des génériques (type, lifetime, ou const) sur les types associés

Le , par Bruno

96PARTAGES

8  0 
L'équipe Rust a annoncé la disponibilité de Rust 1.65, les types génériques associés ou GATs (generic associated types) seront stables - plus de six ans et demi après l'ouverture du RFC original. Il s'agit d'une réalisation monumentale. Cependant, comme pour certaines autres fonctionnalités de Rust, telles que les génériques asynchrones ou const, il existe des limitations dans la stabilisation initiale que l'équipe Rust prévoit de supprimer à l'avenir.


Les GATs (generic associated types) ont été initialement proposés dans la RFC 1598. Ils permettent de définir des génériques de type, de durée de vie ou de constantes sur des types associés. Si vous êtes familier avec les langages qui ont des « types supérieurs », vous pourriez appeler les GATs des constructeurs de type sur les traits.

Que sont les types génériques associés ?

À la base, les types associés génériques permettent d'avoir des génériques (type, lifetime, ou const) sur les types associés. Notons que cela ne fait que compléter les endroits où il est possible de placer des génériques : par exemple, il est déjà possible d'avoir des génériques sur les alias de type indépendants et sur les fonctions dans les traits. Maintenant, il est simplement possible d'avoir des génériques sur les alias de type dans les traits (qui sont simplement appelés les types associés). Voici un exemple de ce à quoi ressemblerait un trait avec un GAT :

Code : Sélectionner tout
1
2
3
4
5
trait LendingIterator { 
    type Item<'a> where Self: 'a; 
 
    fn next<'a>(&'a mut self) -> Self::Item<'a>; 
}

Quelques bugs et limites actuels

Comme nous l'avons déjà mentionné, cette stabilisation n'est pas exempte de bogues et de limites. Ce n'est pas atypique par rapport à des fonctionnalités antérieures de grands langages. L'équipe Rust prevoit de corriger ces bogues et de supprimer ces limitations dans le cadre des efforts continus menés par l'équipe des types nouvellement formée. Ici, nous allons passer en revue quelques-unes des limitations que nous avons identifiées et que les utilisateurs pourraient rencontrer.

Considérons le code suivant :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
trait LendingIterator { 
    type Item<'a> where Self: 'a; 
} 
 
pub struct WindowsMut<'x, T> { 
    slice: &'x [T], 
} 
 
impl<'x, T> LendingIterator for WindowsMut<'x, T> { 
    type Item<'a> = &'a mut [T] where Self: 'a; 
} 
 
fn print_items<I>(iter: I) 
where 
    I: LendingIterator, 
    for<'a> I::Item<'a>: Debug, 
{ ... } 
 
fn main() { 
    let mut array = [0; 16]; 
    let slice = &mut array; 
    let windows = WindowsMut { slice }; 
    print_items::<WindowsMut<'_, usize>>(windows); 
}

Imaginons ici que nous voulions avoir un LendingIterator dont les éléments sont des tranches superposées d'un tableau. Nous avons également une fonction print_items qui imprime tous les éléments d'un LendingIterator, pour autant qu'ils implémentent Debug. La plupart de ces éléments devraient vous sembler familiers ; ce trait est très similaire au trait Iterator de la bibliothèque standard. Fondamentalement, cette version du trait permet à la fonction suivante de retourner un élément qui emprunte à self.

Dans l'ensemble, même si vous n'avez pas besoin d'utiliser les GATs directement, il est très possible que les bibliothèques que vous utilisez utilisent les GATs en interne ou en public pour des raisons d'ergonomie, de performance ou simplement parce que c'est la seule façon dont l'implémentation fonctionne. Sans entrer dans les détails ici, le for<'a> I::Item<'a> : Debug implique actuellement que I::Item<'a> doit survivre 'static.

« Ce n'est pas vraiment un bug sympathique. Et de tous ceux que nous mentionnerons aujourd'hui, ce sera probablement celui qui sera le plus contraignant, le plus ennuyeux et le plus difficile à résoudre. Il apparaît beaucoup plus souvent avec les GATs, mais peut être trouvé dans du code qui n'utilise pas du tout les GATs. Malheureusement, la correction de ce problème nécessite quelques remaniements du compilateur, ce qui n'est pas un projet à court terme. C'est pourtant un projet à l'horizon. La bonne nouvelle est que, dans l'intervalle, nous travaillons à l'amélioration du message d'erreur que vous obtenez avec ce code. Voici à quoi il ressemblera lors de la prochaine stabilisation :

error[E0597]: `array` does not live long enough
|
| let slice = &mut array;
| ^^^^^^^^^^ borrowed value does not live long enough
| let windows = WindowsMut { slice };
| print_items::<WindowsMut<'_, usize>>(windows);
| -------------------------------------------- argument requires that `array` is borrowed for `'static`
| }
| - `array` dropped here while still borrowed
|
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
|
| for<'a> I::Item<'a>: Debug,
| ^^^^


Ce n'est pas parfait, mais c'est quelque chose. Cela ne couvre peut-être pas tous les cas, mais si vous avez un for<'a> I::Item<'a> : Trait lié quelque part et que vous obtenez une erreur indiquant que quelque chose...
La fin de cet article est réservée aux abonnés. Soutenez le Club Developpez.com en prenant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !