diff --git a/FRENCH/src/07_workarounds/03_send_approximation.md b/FRENCH/src/07_workarounds/03_send_approximation.md new file mode 100644 index 00000000..afb9ee4c --- /dev/null +++ b/FRENCH/src/07_workarounds/03_send_approximation.md @@ -0,0 +1,243 @@ + + +# L'approximation de `Send` + + + +Certaines machines à état de fonctions asynchrones sont sûres pour être +envoyées entre des processus, alors que d'autres ne le sont pas. Le fait que la +`Future` d'une fonction asynchrone est `Send` ou non est conditionné par le +fait qu'un type `Send` soit maintenu par un `.await`, mais cette approche est +aujourd'hui trop conservatrice sur certains points. + + + +Par exemple, imaginez un simple type qui n'est pas `Send`, comme un type qui +contient un `Rc` : + + + +```rust +use std::rc::Rc; + +#[derive(Default)] +struct EstPasSend(Rc<()>); +``` + + + +Les variables du type `EstPasSend` peuvent intervenir brièvement dans des +fonctions asynchrones même si le type résultant de la `Future` retournée par la +fonction asynchrone doit être `Send` : + + + +```rust,edition2018 +# use std::rc::Rc; +# #[derive(Default)] +# struct EstPasSend(Rc<()>); +async fn beta() {} +async fn alpha() { + EstPasSend::default(); + beta().await; +} + +fn necessite_send(_: impl Send) {} + +fn main() { + necessite_send(alpha()); +} +``` + + + +Cependant, si nous changeons `alpha` pour stocker le `EstPasSend` dans une +variable, cet exemple ne se compile plus : + + + +```rust,edition2018 +# use std::rc::Rc; +# #[derive(Default)] +# struct EstPasSend(Rc<()>); +# async fn beta() {} +async fn alpha() { + let x = EstPasSend::default(); + beta().await; +} +# fn necessite_send(_: impl Send) {} +# fn main() { +# necessite_send(alpha()); +# } +``` + + + +``` +error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely + -- > src/main.rs:15:5 + | +15 | necessite_send(foo()); + | ^^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely + | + = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` + = note: required because it appears within the type `EstPasSend` + = note: required because it appears within the type `{EstPasSend, impl std::future::Future, ()}` + = note: required because it appears within the type `[static generator@src/main.rs:7:16: 10:2 {EstPasSend, impl std::future::Future, ()}]` + = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:7:16: 10:2 {EstPasSend, impl std::future::Future, ()}]>` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `impl std::future::Future` +note: required by `necessite_send` + -- > src/main.rs:12:1 + | +12 | fn necessite_send(_: impl Send) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +``` + + + +Cette erreur est justifiée. Si nous stockons `x` dans une variable, il ne sera +pas libéré avant d'arriver après le `.await`, moment où la fonction asynchrone +s'exécute peut-être sur un processus différent. Comme `Rc` n'est pas `Send`, +lui permettre de voyager entre les processus ne serait pas sain. Une solution +simple à cela serait de libérer le `Rc` avec `drop` avant le `.await`, mais +malheureusement cela ne fonctionne pas aujourd'hui. + + + +Pour contourner ce problème, vous pouvez créer une portée de bloc qui englobe +chacune des variables qui ne sont pas `Send`. Cela permet de dire facilement au +compilateur que ces variables ne vivent plus en dehors de l'utilisation du +`.await`. + + + +```rust,edition2018 +# use std::rc::Rc; +# #[derive(Default)] +# struct EstPasSend(Rc<()>); +# async fn beta() {} +async fn alpha() { + { + let x = EstPasSend::default(); + } + beta().await; +} +# fn necessite_send(_: impl Send) {} +# fn main() { +# necessite_send(alpha()); +# } +``` diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index beeca743..854c980f 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -1,3 +1,5 @@ # Table des matières + - [L'approximation de `Send`](07_workarounds/03_send_approximation.md) + [Traduction des termes](translation-terms.md)