|
| 1 | +--- |
| 2 | +references: |
| 3 | + - type: web |
| 4 | + title: Specialization |
| 5 | + url: https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md |
| 6 | + id: RFC-1210 |
| 7 | +--- |
| 8 | + |
1 | 9 | # Bibliothèque standard |
2 | 10 |
|
3 | 11 | ## Les traits `Send` et `Sync` |
@@ -260,3 +268,85 @@ sont nécessaires. Toute implémentation manuelle d'un trait de comparaison |
260 | 268 | standard DEVRAIT être justifiée et documentée. |
261 | 269 |
|
262 | 270 | </div> |
| 271 | + |
| 272 | +## Trait `Drop` : le destructeur |
| 273 | + |
| 274 | +Les types implémentent le trait `std::ops::Drop` dans le but d'effectuer |
| 275 | +certaines opérations lorsque la mémoire associée à une valeur est réclamée. |
| 276 | +`Drop` est l'équivalent Rust d'un destructeur en C++ ou un finaliseur en Java. |
| 277 | + |
| 278 | +<div class="note"> |
| 279 | + |
| 280 | +Implémenter ce traits modifie la sémantique d'exécution du langage. En effet, |
| 281 | +contrairement au fonctionnement classique des traits [^1], l'exécution d'un même code |
| 282 | +se verra différente avec et sans cette implémentation. |
| 283 | + |
| 284 | +[^1]: excepté l'usage de contraintes négatives de type, permis par exemple par la [@RFC-1210], |
| 285 | +pas encore implémentée pour la version actuelle de Rust (1.91.0) |
| 286 | + |
| 287 | +</div> |
| 288 | + |
| 289 | +`Drop` agit récursivement, depuis la valeur externe vers les valeurs imbriquées. |
| 290 | +Lorsqu'une valeur sort du scope (ou est explicitement relâchée avec |
| 291 | +`std::mem::drop`), elle est relâchée en deux étapes. La première étape a lieu |
| 292 | +uniquement si le type de la valeur en question implémente le trait `Drop` et |
| 293 | +consiste en l'appel de la méthode `drop`. La seconde étape consiste en la |
| 294 | +répétition de processus de *drop* récursivement sur tous les champs que contient |
| 295 | +la valeur. Il est à noter que l'implémentation de `Drop` est |
| 296 | +*responsable uniquement de la valeur extérieure*. |
| 297 | + |
| 298 | +Tout d'abord, l'implémentation de `Drop` ne doit pas être systématique. Elle est |
| 299 | +nécessaire uniquement lorsque le type requiert un traitement logique à la |
| 300 | +destruction. `Drop` est typiquement utilisé dans le cas du relâchement des |
| 301 | +ressources externes (connexions réseau, fichier, etc.) ou de ressources mémoire |
| 302 | +complexes (*smart pointers* comme les `Box` ou les `Rc` par exemple). Au |
| 303 | +final, il est probable que l'implémentation du trait `Drop` contienne des blocs |
| 304 | +`unsafe` ainsi que d'autres opérations critiques du point de vue de la sécurité. |
| 305 | + |
| 306 | +<div class="reco" id="LANG-DROP" type="Règle" title="Justification de l'implémentation du trait `Drop`"> |
| 307 | + |
| 308 | +Dans un développement sécurisé en Rust, l'implémentation du trait |
| 309 | +`std::ops::Drop` DOIT être justifiée et documentée. |
| 310 | + |
| 311 | +</div> |
| 312 | + |
| 313 | +Ensuite, le système de types de Rust assure seulement la sûreté mémoire et, |
| 314 | +du point de vue du typage, des `drop`s peuvent tout à fait être manqués. |
| 315 | +Plusieurs situations peuvent mener à manquer des `drop`s, comme : |
| 316 | + |
| 317 | +- un cycle dans la référence (par exemple avec `Rc` ou `Arc`) ; |
| 318 | +- un appel explicite à `std::mem::forget` (ou `core::mem::forget`) (voir |
| 319 | + paragraphe à propos de [`forget` et des fuites de mémoire](unsafe/memory.md#forget-and-memory-leaks)) ; |
| 320 | +- un `panic` dans un `drop` ; |
| 321 | +- un arrêt du programme (et un `panic` lorsque `abort-on-panic` est activé). |
| 322 | + |
| 323 | +Les `drop`s manqués peuvent mener à l'exposition de données sensibles ou bien |
| 324 | +encore à l'épuisement de ressources limitées et par là même à des problèmes |
| 325 | +d'indisponibilité. |
| 326 | + |
| 327 | +<div class="reco" id="LANG-DROP-NO-PANIC" type="Règle" title="Absence de `panic` dans l'implémentation de `Drop`"> |
| 328 | + |
| 329 | +Dans un développement sécurisé en Rust, l'implémentation du trait |
| 330 | +`std::ops::Drop` NE DOIT PAS causer de `panic`. |
| 331 | + |
| 332 | +</div> |
| 333 | + |
| 334 | +En plus des `panic`s, les `drop`s contenant du code critique doivent être |
| 335 | +protégés. |
| 336 | + |
| 337 | +<div class="reco" id="LANG-DROP-NO-CYCLE" type="Règle" title="Absence de cycles de références avec valeurs `Drop`ables"> |
| 338 | + |
| 339 | +Les valeurs dont le type implémente `Drop` NE DOIVENT PAS être incluses, |
| 340 | +directement ou indirectement, dans un cycle de références à compteurs. |
| 341 | + |
| 342 | +</div> |
| 343 | + |
| 344 | +<!-- --> |
| 345 | + |
| 346 | +<div class="reco" id="LANG-DROP-SEC" type="Règle" title="Sécurité assurée par d'autres mécanismes en plus du trait `Drop`"> |
| 347 | + |
| 348 | +Certaines opérations liées à la sécurité d'une application à la fin d'un |
| 349 | +traitement (comme l'effacement de secrets cryptographiques par exemple) NE DOIVENT PAS |
| 350 | +reposer uniquement sur l'implémentation du trait `Drop`. |
| 351 | + |
| 352 | +</div> |
0 commit comments